本文共 4372 字,大约阅读时间需要 14 分钟。
在使用requests-html的过程中,有时候会遇到网站因为检测到请求头是无头浏览器而禁 Readonly访问的情况。这时候,我们可以通过模拟浏览器来解决这个问题。
一种常用的方式是修改requests-html的源码,增加相关的模拟浏览器配置。以下是一个示例代码片段,可以帮助你设置一个完整的修复方案:
import requests_htmlfrom requests_html import HTMLSession, Browser# 初始化浏览器browser = Browser quietly= True) # 设置浏览器配置headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"}# 发送请求response = browser.get(url, timeout=90, headers=headers)# 处理编码问题response.encoding = requests.utils.get_encodings_from_content(response.text)[0] if requests.utils.get_encodings_from_content(response.text) else response.apparent_encoding# 渲染页面html = response.html.render()# 自定义过滤函数,根据需求进行调整def filter_tags_content(html_content): # 请根据实际需要添加过滤逻辑 passcontent = filter_tags_content(response.text)
在请求返回时,可能会遇到页面使用不同编码的pt问题。requests-html提供了一些工具来自动处理编码问题:
import requests_htmlresponse = session.get(url, timeout=90, headers=headers)# 提取页面内容并识别编码encodings = requests.utils.get_encodings_from_content(response.text)if encodings: response.encoding = encodings[0]else: response.encoding = response.apparent_encoding# 提取内容page_text = response.text
有时候,网络延迟或者服务器问题导致请求超时。可以通过设置一个更高的超时值来提高成功率:
import requests_htmlresponse = session.get(url, timeout=90, headers=headers)if response.status_code == 404: print("页面未找到")elif response.status_code == 500: print("服务器错误")else: print("请求成功)
当遇到需要使用代理池访问时,可以通过设置代理客户端来实现:
from requests_html import HTMLSessionsession = HTMLSession()proxies = { 'http': 'http://10.10.1.10:3128', 'https': 'http://10.10.1.10:1080'}response = session.get(url, proxies=proxies, headers=headers)# 检查代理IP是否有效if response.status_code in [401, 403]: print("代理认证错误,可能需要手动更换代理IP")
由于有些页面可能存在反爬机制,或者内容需要完整加载才能正确提取信息。我们可以使用 Imagineo 来辅助完成页面渲染:
import requests_htmlresponse = session.get(url, timeout=90, headers=headers)response.html.render() # 渲染页面# 提取内容page_text = response.text# 使用 Imagineo 进行解析(可选)import cheerioarticle = cheerio LOAD(state=response).article
如果网站使用验证码或输入验证,那么可能需要结合图像识别技术或otherguelta方法:
# 发送请求,模拟输入验证码内容import re# 发送请求,模拟手动输入response = session.post(url, data={'验证码': '123456'}, headers=headers)# 使用 zumifino库 检测验证码from zumifino import zbc# 提取验证码内容vcode = re.findall(r'[0-9]{4}', response.text)if len(vcode) >=4 and vcode.isdigit(): real_vcode = vcode[:4] # 提交真实验证码到服务器,请求接下去的内容 # 完成后续请求 response = session.post(其他URL, data=..., headers=headers)
在使用过程中,添加日志记录和异常处理可以更好地定位问题:
import logginglogger = logging.getLogger(__name__)try: response = session.get(url, timeout=90, headers=headers)except requests.exceptions.RequestException as e: logger.error("请求异常:%s" % str(e)) # 提前处理可能的错误情况
如果你的目标是自动切换代理池,可以直接在请求中设置代理池客户端:
# 初始化代理池客户端from requests_html import Sessionproxies = { '%(public_ip)s': 'http://%(public_ip)s:1080',}response = session.get(url, proxies=proxies, headers=headers)if response.status_code == 403: print("被网站封锁了,需要切换代理")
通过结合requests-html和Cheerio,可以更方便地解析页面内容:
import requests_htmlfrom requests_html import HTMLSessionfrom cheerio import Link, needs_refreshsession = HTMLSession()response = session.get(url, timeout=90, headers=headers)if response.status_code == 200: page = response.htmlParsed for element in page.elements: print(element)
确保请求头设置正确,包括正确的User-A get-action和有限的内容长度:
from requests_html import HTMLSessionimport reheaders = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36', 'Content-Length': '1000',}response = session.get(url, timeout=90, headers=headers)
对于动态加载的网页,可以使用JavaScript渲染工具:
import requests_htmlfrom requests_html import HTMLSessionimport timesession = HTMLSession()def render_page(url, session): response = session.get(url, timeout=90, headers=headers) if response.status_code == 200: time.sleep(1) # 避免被封IP response.html.render() return response.htmlpage = render_page(url, session)content = page.find('body').text
为了确保所有请求头设置正确,可以使用 spies 工具:
import spies@spies mask('GET', 'http://example.com/')def test(): requests.get('http://example.com/') test()
通过以上方法,你可以基于需求进行相应的优化和调整,确保请求过程的顺利进行,同时保护自己免受反爬机制的限制。
转载地址:http://yhhkk.baihongyu.com/