最近学习python爬虫,在用requests爬取非正版小说网站时遇到问题,恳请各位解惑。我的目的是爬取一部小说,方法是先获取目录页的链接,然后依次访问并爬取文本,其中先后出现两种问题:
- 爬虫运行初期较为顺利,一定次数(10-40次)后频繁出现“max retries exceed with url”错误,估计是被服务器封锁IP,即便使用高匿IP也无法避免。一旦发生,更换IP也无法访问,只能等待解封。起初尝试关闭connection和增加等待时间,无果,后通过增加重连次数的方式,程序基本得以运行,但问题没有得到解决。
- 在规避上述问题后,新问题又产生了。在爬取40余次后,返回代码就变为403,无法获取内容,同上,更换IP也无法避免。
def get_html(url):
proxies = {
'https': '106.15.107.36:3128'
} # 免费高匿ip
headers = {
'User-Agent': random.random(agent-list), # 随机user-agent
'Referer': lambda x: re.search(
"^((http://)|(https://))?([a-zA-Z0-9]([a-zA-Z0-9-+]{0,61}[a-zA-Z0-9])?.+)+[a-zA-Z]{2,6}(/)", url).group(), # 正则表达式获取referer
'DNT': "1",
'Accept': 'text/novel_html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,'
'application/signed-exchange;v=b3;q=0.9',
'Connection': 'close', # 关闭链接
'Accept-Language': 'zh-CN,zh;q=0.9,en-CN;q=0.8,en;q=0.7',
'Accept-Encoding': 'gzip, deflate, br',
}
i = 0
while i < 3: # retry三次
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=5) # 传递完整参数
response.encoding = response.apparent_encoding
response.keep_alive = False # 再次关闭链接
except requests.exceptions.RequestException as e:
i += 1
print(e)
time.sleep(5)
else:
text = unicodedata.normalize('NFKC', response.text) # 格式化,避免/xa0等占位字符
html = pyquery.PyQuery(text)
return html
部分代码如上,爬取小说目录和章节都是调用这个函数。为解决上述两种问题,我参阅了大量类似代码,都没有找到明确结论。我想非正版小说网站通常不会具备如此强大的反爬机制,然而我向request传递了完整的headers、proxies和render都不能完整爬取,而其他示例中往往只传递user-agent就能完成。
期望能有同志解答其中的逻辑关系,如不吝赐教,本人感激不尽。