「Python」爬虫-10.代理与常见报错

本文涉及的产品
云服务器 ECS,每月免费额度200元 3个月
云服务器ECS,u1 2核4GB 1个月
简介: 本文就关于爬虫**代理**以及在爬虫过程中可能出现的**报错**做一个汇总。

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情


前言

1.本文重点

本文就关于爬虫代理以及在爬虫过程中可能出现的报错做一个汇总。

如果,感兴趣的话,就继续往下看吧, 不感兴趣的快run,开个玩笑

2.参考链接

为什么网站知道我的爬虫使用了代理? - 知乎 (zhihu.com)

写Python爬虫又被屏蔽了,你现在需要一个稳定的代理IP-CSDN

3.推广一波

关于爬虫入门,你可以先光顾一下我的专栏,Python学习 - xincheng_q的专栏 - 掘金 (juejin.cn)

专栏内容循序渐进,涉及到的均是爬虫基础内容 主要是难得我也不会

「Python」爬虫-1.入门知识简介 - 掘金 (juejin.cn)

「Python」爬虫-2.xpath解析和cookie,session - 掘金 (juejin.cn)

「Python」爬虫-3.防盗链处理 - 掘金 (juejin.cn)

「Python」爬虫-4.selenium的使用 - 掘金 (juejin.cn)

「Python」爬虫-5.m3u8(视频)文件的处理 - 掘金 (juejin.cn)

「Python」爬虫-6.爬虫效率的提高 - 掘金 (juejin.cn)

「Python」爬虫-7.验证码的识别 - 掘金 (juejin.cn)

「Python」爬虫-8.断点调试-网易云评论爬取 - 掘金 (juejin.cn)

「Python」爬虫-9.Scrapy框架的初识-公交信息爬取 - 掘金 (juejin.cn)

代理

关于代理,为什么要用代理?

大多数回答是:假如你疯狂访问同一个网站,并且该网站会检测某一段时间某个IP 的访问次数,最后的可能的结果就是你被禁止访问该网站了。

这里讲一个小故事吧:

在学校期间老师要求我们每天都进到一个系统进行安全上报,上报的系统记录了你的登录状态以及你第一次填写的信息,均属于表单的形式。

如果是手动上报的话,每天需要做的就是:打开微信->找到公众号->找到上报入口->漫长的等待(有时候人多会极度卡顿,以至于上报页面一直出不来)->页面加载完成->补充自己的信息->点击提交按钮。

每天都是重复的操作,如果页面不卡顿,我就当是图一乐,每天打卡还能接受,但是它卡顿啊!(抓狂💀, 不行,还是得想办法整一个自动上报的东西。

于是,通过各种方法,白嫖到了自动上报的代码,然后自己刚好有个轻量级服务器,就开了个定时任务,让他每天都执行。

刚开始,一直都非常的顺利,直到有一天,有人戳了戳你,说你今天咋没上报啊,我去,心想:坏了,不会是程序出问题了吧。(虽然说弄了自动推送短信的功能,但是,由于太懒,每天也没仔细看) 进去一看,运行,“Max retries exceeded with url...”,我一个小白看到这就封了啊,一顿请教+百度,听说是学校把湖北省外的IP都给封了,所以暂且不能用其他地方的IP上报了。
心里又一顿骂骂咧咧...

当你的程序对某一个网站请求过于频繁,并且对方通过某些机制检测到你的行为属于爬虫的话,他就又会通过某些手段,对IP就进行限制甚至拉黑。像我故事中说的那样,一种解决方法就是自己添加区域代理。

所以,玩爬虫的时候还是有必要了解一些代理的知识的。

IP代理

先列举一些代理IP的网站,大家有需求的可以自取(为什么链接格式没有对齐,我不理解

免费代理IP                   https://www.zdaye.com/Free/
免费代理IP              http://ip.yqie.com/ipproxy.htm
66免费代理网         http://www.66ip.cn/
89免费代理              http://www.89ip.cn/
无忧代理              http://www.data5u.com/
云代理               http://www.ip3366.net/
快代理               https://www.kuaidaili.com/free/
极速专享代理                 http://www.superfastip.com/
HTTP代理IP            https://www.xicidaili.com/wt/
小舒代理              http://www.xsdaili.com
西拉免费代理IP         http://www.xiladaili.com/
小幻HTTP代理         https://ip.ihuan.me/
全网代理IP             http://www.goubanjia.com/
飞龙代理IP             http://www.feilongip.com/

一般初学者,可能会用到以下方法去使用代理IP:

import requests  
  
resp1 = requests.get('https://httpbin.org/ip').text
resp2 = requests.get('https://httpbin.org/ip', proxies={'http': 'xxx'}).text  

image.png

为什么使用了代理以后,IP没有变呢?

这是因为你根本没有给https网站使用代理,你的代理只会对http网站生效。要对https网站生效,需要给它指定相应的https代理:

resp = requests.get('xxx', proxies={'http': 'xx:port', 'https': 'xx:port'}).text

这里贴出一段使用代理的模板:(没错,又是板子

import requests

proxies = {
    "https": "https://58.209.234.8:3389",
    "http": "http://10.10.1.10:3128",
    "https": "https://10.10.1.10:1080",
}
resp = requests.get("https://www.baidu.com", proxies=proxies, verify=False)
resp.encoding = 'utf-8'
print(resp.text)

可能被识别的几种情况:

  • 你的代理IP不是高匿代理

代理IP有三种常见的类型,透明代理,匿名代理和高匿代理。

使用透明代理的时候,网站可以同时看到代理IP和你的真实IP。用了等于白用。

使用匿名代理的时候,网站看不到你的真实IP,但是在请求里面有一个特征,可以告诉网站,你正在使用代理访问。

而只有真正的高匿代理,才能把你的爬虫请求隐藏起来。
有一些同学可能会从网上搜索免费的代理IP来使用。但这里面很多代理并不是高匿代理。肯定会被发现。

  • 你的代理IP是服务器IP

有很多代理供应商,他们批量采购云服务器来搭建代理服务。例如国内的供应商会采购阿里云、腾讯云、华为云的服务器来搭建代理。海外的供应商会采购AWS或者Google云服务器。

如果你在云服务器上跑过不加代理的爬虫,你会发现,有时候一个爬虫,不加代理,在自己电脑上跑一点问题都没有(啊对对对) 但是在云服务器上一跑就会被识别。这是因为云服务器的IP地址范围跟家用宽带是不一样的。

像AWS和Google云,他们的云服务器IP范围是公开的,只要网站提前把来自这个范围的所有请求全部禁掉,那么从AWS、Google云服务器上面发起的请求直接就会被当做爬虫请求。因此搭建在上面的代理服务自然就不会生效了。

国内的云服务供应商的服务器IP地址是否公布过我不太清楚,但他们的IP范围肯定是跟家用IP不一样的。网址遇到来自这些可疑IP范围的请求时,虽然不一定完全封禁,但是弹一个验证码出来测一测,还是可以挡住很多爬虫。

遇到这种情况,爬虫只有设法采购一些使用家用宽带搭建代理服务的供应商,才能解决问题。但这种代理价格肯定会翻好几倍。

  • 服务器供应商的IP池被污染

有些人的爬虫写得非常垃圾,自以为有代理就无所畏惧,爬虫请求漏掉百出,网站即使不检查IP频率,也可以从其它特征知道这是爬虫请求,于是网站就会连带着这个代理IP一起封掉。而偏偏这种垃圾爬虫的请求速度又极快。哪怕代理供应商的IP池中有几百万个IP,也会很快被这些垃圾爬虫全部害死。

国内头部网站每天都会被数以千万计的爬虫请求访问,而主流的代理供应商就那么几家。如果很多垃圾爬虫都选中了同一家供应商,而他们的代理池更新又不及时。那么你使用了这家供应商的代理IP,自然一来就会被发现。

  • 代理不支持HTTP/2

有一些网站需要使用HTTP/2请求。在Python里面,已经有不少HTTP客户端库支持发起HTTP/2的请求了,例如httpx。但是,现在很少有代理供应商能提供支持HTTP/2的代理,因为它搭建起来比较麻烦。于是,当你使用了支持HTTP/2的客户端,通过一个HTTP/1.1的代理IP访问一个HTTP/2的网站的时候,网站并不能正常返回内容。

上述资料来源: 为什么网站知道我的爬虫使用了代理? - 知乎 (zhihu.com),侵权立删。

User-Agent代理池

User-Agent即用户代理,简称UA,它是一个特殊 字符串头,使得服务器能够识别客户使用的 操作系统及版本、CPU类型、 浏览器及版本浏览器渲染引擎、浏览器语言、 浏览器插件等。

【UA标准格式】:
浏览器标识 (操作系统标识; 加密等级标识; 浏览器语言) 渲染引擎标识 版本信息

举个例子:

user-agent:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/xxx.0.0.0 Safari/xxx.36 Edg/xxx.0.1418.52

Mozilla/5.0浏览器标识,(Windows NT 10.0; Win64; x64)操作系统标识, AppleWebKit/537.36 (KHTML, like Gecko) 渲染引擎标识, Chrome/xxx.0.0.0 Safari/xxx.36 Edg/xxx.0.1418.52浏览器版本

反爬更好的方式是使用User-Agent池来解决
(如生成随机User-Agent)

理解了UA是如何构成的,那么理解生成随机UA应该是不难的。

import random

def get_ua():
    first_num = random.randint(55, 76)
    third_num = random.randint(0, 3800)
    fourth_num = random.randint(0, 140)
    os_type = [
        '(Windows NT 6.1; WOW64)', '(Windows NT 10.0; WOW64)', '(X11; Linux x86_64)',
        '(Macintosh; Intel Mac OS X 10_14_5)'
    ]
    chrome_version = 'Chrome/{}.0.{}.{}'.format(first_num, third_num, fourth_num)

    ua = ' '.join(['Mozilla/5.0', random.choice(os_type), 'AppleWebKit/537.36',
                   '(KHTML, like Gecko)', chrome_version, 'Safari/537.36']
                  )
    return ua

通过上述的自定义函数就可以得到随机UA了。

关于代理池,你还可以参考其他博客:
使用 MongoDB和flask构建一个代理池

报错

我们在学习的过程中总是会遇到各式各样的报错,然后各种爆红总是会让我们心烦意乱以及 掉头发 .
在这里整理了部分在爬虫学习的过程中可能出现的报错,仅供参考。

SSLError证书错误

requests.exceptions.SSLError: HTTPSConnectionPool(host='www.baidu.com', port=443)
image.png
原因
SSL证书报错

http连接太多没有关闭导致的。
经过一番查询,发现该错误是因为如下:
http的连接数超过最大限制,默认的情况下连接是Keep-alive的,所以这就导致了服务器保持了太多连接而不能再新建连接。
 
    1、ip被封
    2、程序请求速度过快。

解决方法

参考链接

(1)time.sleep()

(2)关闭 SSL 验证   verify=False

response = requests.get(fpath_or_url,headers=headers,stream=True, verify=False)

(3) requests默认是keep-alive的,可能没有释放,加参数 headers={'Connection':'close'}

# TODO ssl证书报错,参数 verify=False,同时,requests默认是keep-alive的,可能没有释放,加参数                 
sess = requests.Session()
sess.mount('http://', HTTPAdapter(max_retries=3)) 
sess.mount('https://', HTTPAdapter(max_retries=3))     
sess.keep_alive = False # 关闭多余连接

text = requests.get(self.target_img_url, headers=headers, stream=True, verify=False, timeout=(5,5)) #  connect 和 read 二者的 timeout,所以是一个数组

with open(img_files_path, 'wb') as file:
    for i in text.iter_content(1024 * 10):
        file.write(i)

text.close() # 关闭,很重要,确保不要过多的链接

(4) 关闭系统代理(如果你开了ti 子的话

Event loop is closed

场景:协程创建时,会时不时报错RuntimeError: Event loop is closed

报错原因:
aiohttp 内部使用了 _ProactorBasePipeTransport ,程序退出释放内存时自动调用其 del 方法导致二次关闭事件循环。一般的协程程序是不会使用_ProactorBasePipeTransport 的,所以asyncio.run() 还是可以正常运行。而且这种情况仅在Windows上发生。

解决办法:
asyncio.run(getCatalog(url))改为

loop = asyncio.get_event_loop()
loop.run_until_complete(getCatalog(url)) # getCatalog(url)是协程主函数名

image.png
image.png

element click intercepted:

场景:在使用selenium模拟爬取信息时,可能想要点击页面中某个按钮,但是无法点击。

报错原因:大概是因为这个按钮上面还有别的东西覆盖

报错部分原代码:

web.find_element(By.XPATH,
                 '//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3').click()

改为:

h3 = web.find_element(By.XPATH,
                 '//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3')
web.execute_script("arguments[0].click();", h3)

'list' object has no attribute 'click'

可能是find_element_by_xpath 误用为 find_elements_by_xpath

decode()&encode()

python bytes和str两种类型可以通过函数encode()和decode()相互转换,

str→bytes:encode()
方法。str通过encode()方法可以转换为bytes。

bytes→str:decode()
方法。如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法。

Max retries exceeded with url...

原因:大概概率是被封IP了

解决方法:前面讲到的IP池

相关实践学习
一小时快速掌握 SQL 语法
本实验带您学习SQL的基础语法,快速入门SQL。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情: https://www.aliyun.com/product/ecs
相关文章
|
14天前
|
数据采集 XML 数据处理
使用Python实现简单的Web爬虫
本文将介绍如何使用Python编写一个简单的Web爬虫,用于抓取网页内容并进行简单的数据处理。通过学习本文,读者将了解Web爬虫的基本原理和Python爬虫库的使用方法。
|
1天前
|
数据采集 安全 JavaScript
【2024-完整版】python爬虫 批量查询自己所有CSDN文章的质量分:附整个实现流程
【2024-完整版】python爬虫 批量查询自己所有CSDN文章的质量分:附整个实现流程
8 0
|
1天前
|
数据采集 机器学习/深度学习 前端开发
【好书推荐3】Python网络爬虫入门到实战
【好书推荐3】Python网络爬虫入门到实战
9 0
|
1天前
|
数据采集 JSON API
【2024-简洁版】python爬虫 批量查询自己所有CSDN文章的质量分:方便快速上手修改代码
【2024-简洁版】python爬虫 批量查询自己所有CSDN文章的质量分:方便快速上手修改代码
8 0
|
4天前
|
数据采集 Web App开发 Java
Python 爬虫:Spring Boot 反爬虫的成功案例
Python 爬虫:Spring Boot 反爬虫的成功案例
|
4天前
|
数据采集 Python
使用Python实现简单的Web爬虫
本文将介绍如何使用Python编写一个简单的Web爬虫,用于抓取网页上的信息。通过分析目标网页的结构,利用Python中的requests和Beautiful Soup库,我们可以轻松地提取所需的数据,并将其保存到本地或进行进一步的分析和处理。无论是爬取新闻、股票数据,还是抓取图片等,本文都将为您提供一个简单而有效的解决方案。
|
5天前
|
监控 开发者 Python
Python中记录程序报错信息的实践指南
Python中记录程序报错信息的实践指南
13 1
|
5天前
|
数据采集 存储 XML
如何利用Python构建高效的Web爬虫
本文将介绍如何使用Python语言以及相关的库和工具,构建一个高效的Web爬虫。通过深入讨论爬虫的基本原理、常用的爬虫框架以及优化技巧,读者将能够了解如何编写可靠、高效的爬虫程序,实现数据的快速获取和处理。
|
8天前
|
监控 测试技术 持续交付
Python自动化测试代理程序可用性
总之,通过编写测试用例、自动化测试和设置监控系统,您可以确保Python自动化测试代理程序的可用性,并及时发现和解决问题。这有助于提供更可靠和高性能的代理服务。
12 4
|
12天前
|
数据采集 Web App开发 数据可视化
Python爬虫技术与数据可视化:Numpy、pandas、Matplotlib的黄金组合
Python爬虫技术与数据可视化:Numpy、pandas、Matplotlib的黄金组合