python3爬虫系列19之反爬随机 User-Agent 和 ip代理池的使用

站长资讯平台:python3爬虫系列19之随机User-Agent 和ip代理池的使用
我们前面几篇讲了爬虫增速多进程,进程池的用法之类的,爬虫速度加快呢,也会带来一些坏事。

1. 前言
比如随着我们爬虫的速度越来越快,很多时候,有人发现,数据爬不了啦,打印出来一看。

不返回数据,而且还甩一句话

是不是很熟悉啊?

要想想看,人是怎么访问网站的? 发请求,对,那么就会带有

request.headers,

那么当你疯狂请求别人的网站时候,人家网站的管理人员就会 觉得有点不对劲了,

他看看请求的 header 信息,一看吓一跳,结果看到的 headers 信息是这样的:

Host: 127.0.0.1:3369
User-Agent: python-requests/3.21.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
1
2
3
4
5
看到:

User-Agent: python-requests/3.21.0

居然使用 python 的库来请求,说明你已经暴露了,人家不封你才怪呢?

那么怎么办呢?伪装自己呗。

python 不可以伪装,浏览器可以伪装,所以可以修改浏览器的请求头。

简单来说,就是让自己的 python 爬虫假装是浏览器。

2. 伪装 Header的哪个地方?
要让自己的 python 爬虫假装是浏览器,我们要伪装headers,那么headers里面有很多字段,我们主要注意那几个呢?

headers数据通常用这两个即可,强烈推荐在爬虫中为每个request都配个user-agent,而’Referer’如果需要就加,不需要就不用。(Referer是什么?后面补充知识点)

图示:

上面几个重要点解释如下:

Requests Headers:
• “吾是人!”——修改user-agent:里面储存的是系统和浏览器的型号版本,通过修改它来假装自己是人。

• “我从台湾省来”——修改referer:告诉服务器你是通过哪个网址点进来的而不是凭空出现的,有些网站会检查。

• “饼干!”:——带上cookie,有时带不带饼干得到的结果是不同的,试着带饼干去“贿赂”服务器让她给你完整的信息。

3.headers的伪装—随机User-Agent
爬虫机制:很多网站都会对Headers的User-Agent进行检测,还有一部分网站会对Referer进行检测(一些资源网站的防盗链就是检测Referer)

随机User-Agent生成 :生成一个随机的User-Agent,这样你就可以是很多不同的浏览器模样。

(代码现成的,复制拿去用即可)

#!/usr/bin/python3

#@Readme : 反爬之headers的伪装

# 对于检测Headers的反爬虫
from fake_useragent import UserAgent # 下载:pip install fake-useragent

ua = UserAgent() # 实例化,需要联网但是网站不太稳定-可能耗时会长一些

# 1.生成指定浏览器的请求头
print(ua.ie)
print(ua.opera)
print(ua.chrome)
print(ua.google)
print(ua.firefox)
print(ua.safari)
# 随机打印一个浏览器的User-Agent
print(ua.random)
print('完毕。')

# 2.在工作中常用的则是ua.random方式
import requests
ua = UserAgent()
print(ua.random) # 随机产生

headers = {
'User-Agent': ua.random # 伪装
}

# 请求
url = 'https://www.baidu.com/'
response = requests.get(url, headers=headers)
print(response.status_code)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Referer的伪装:

如果想爬图片,图片反盗链的话就要用到Referer了。

headers = {'User-Agent':ua.random,'Referer':'这里放入图片的主页面'}
1
如果遇到防盗链的图片,一般思路就是先爬到所有图片的地址.jpg —–>将它们储存在列表中 —–>遍历访问图片地址,然后用 ‘wb’的格式打开文件写入,文件名根据图片地址动态改变。

这个基本上如果你的爬虫对象不是很严肃的图片网站,都不会用到。

4.ip要被封禁?ip代理的使用
有的时候,仅仅伪装headers,使用随机 User-Agent来请求也会被发现,同一个ip地址,访问的次数太多,ip会被屏蔽,就用其他的ip继续去访问。

4.1 requests 的代理访问
首先,在python中使用requests 库来代理访问为例。

使用代理 ip 来访问网站如下:

首先要自己定义代理IP代理:

proxie = {
'http' : 'http://xx.xxx.xxx.xxx:xxxx',
'http' : 'http://xxx.xx.xx.xxx:xxx',
....
}
1
2
3
4
5
然后使用requests+代理来请求网页:

response = requests.get(url,proxies=proxies)
1
这样就可以使用你定义的代理地址去访问网站了。

但是,ip地址,是唯一的,从哪里去搞一堆ip地址来使用呢?

在网上有很多免费的代理,代理IP很不稳定。如果你有钱的话,直接去买就行了。


4.2 不花钱?那就是IP代理池
如果你又不想花钱,又想用ip爬虫。那就只能整个ip代理池了。

4.2.1 自建的ip代理池—多线程爬虫
就是自己去收集网上公开的免费ip,自建起 自己的ip代理池。

就是通过 python 程序去抓取网上大量免费的代理 ip , 然后定时的去检测这些 ip 可不可以用,那么下次你要使用代理 ip 的时候,你只需要去自己的 ip 代理池里面拿就行了。

简单来说:访问免费代理的网站 —> 正则/xpath提取 ip和端口—> 测试ip是否可用 》》可用则保存 》》使用ip爬虫 > 过期,抛弃ip。

这个过程可以使用多线程或异步的方式,因为检测代理是个很慢的过程。

这是来源于网络的一个西刺代理的多线程ip代理爬虫:(我不用)

来自于:https://www.jianshu.com/p/2daa34a435df

#!/usr/bin/python3

#@Readme : IP代理==模拟一个ip地址去访问某个网站(爬的次数太多,ip被屏蔽)

# 多线程的方式构造ip代理池。
from bs4 import BeautifulSoup
import requests
from urllib import request, error
import threading

import os
from fake_useragent import UserAgent


inFile = open('proxy.txt') # 存放爬虫下来的ip
verifiedtxt = open('verified.txt') # 存放已证实的可用的ip

lock = threading.Lock()

def getProxy(url):
# 打开我们创建的txt文件
proxyFile = open('proxy.txt', 'a')

# 伪装
ua = UserAgent()
headers = {
'User-Agent': ua.random
}

# page是我们需要获取多少页的ip,这里我们获取到第9页
for page in range(1, 10):
# 通过观察URL,我们发现原网址+页码就是我们需要的网址了,这里的page需要转换成str类型
urls = url + str(page)
# 通过requests来获取网页源码
rsp = requests.get(urls, headers=headers)
html = rsp.text
# 通过BeautifulSoup,来解析html页面
soup = BeautifulSoup(html,'html.parser')
# 通过分析我们发现数据在 id为ip_list的table标签中的tr标签中
trs = soup.find('table', id='ip_list').find_all('tr') # 这里获得的是一个list列表
# 我们循环这个列表
for item in trs[1:]:
# 并至少出每个tr中的所有td标签
tds = item.find_all('td')
# 我们会发现有些img标签里面是空的,所以这里我们需要加一个判断
if tds[0].find('img') is None:
nation = '未知'
locate = '未知'
else:
nation = tds[0].find('img')['alt'].strip()
locate = tds[3].text.strip()
# 通过td列表里面的数据,我们分别把它们提取出来
ip = tds[1].text.strip()
port = tds[2].text.strip()
anony = tds[4].text.strip()
protocol = tds[5].text.strip()
speed = tds[6].find('div')['title'].strip()
time = tds[8].text.strip()
# 将获取到的数据按照规定格式写入txt文本中,这样方便我们获取
proxyFile.write('%s|%s|%s|%s|%s|%s|%s|%s\n' % (nation, ip, port, locate, anony, protocol, speed, time))


def verifyProxyList():
verifiedFile = open('verified.txt', 'a')

while True:
lock.acquire()
ll = inFile.readline().strip()
lock.release()
if len(ll) == 0: break
line = ll.strip().split('|')
ip = line[1]
port = line[2]
realip = ip + ':' + port
code = verifyProxy(realip)
if code == 200:
lock.acquire()
print("---Success成功:" + ip + ":" + port)
verifiedFile.write(ll + "\n")
lock.release()
else:
print("---Failure失败:" + ip + ":" + port)


def verifyProxy(ip):
'''
验证代理的有效性
'''
ua = UserAgent()
requestHeader = {
'User-Agent': ua.random
}
url = "http://www.baidu.com"
# 填写代理地址
proxy = {'http': ip}
# 创建proxyHandler
proxy_handler = request.ProxyHandler(proxy)
# 创建opener
proxy_opener = request.build_opener(proxy_handler)
# 安装opener
request.install_opener(proxy_opener)

try:
req = request.Request(url, headers=requestHeader)
rsq = request.urlopen(req, timeout=5.0)
code = rsq.getcode()
return code
except error.URLError as e:
return e


if __name__ == '__main__':
# 手动新建两个文件
filename = 'proxy.txt'
filename2 = 'verified.txt'
if not os.path.isfile(filename):
inFile = open(filename, mode="w", encoding="utf-8")
if not os.path.isfile(filename2):
verifiedtxt = open(filename2, mode="w", encoding="utf-8")
tmp = open('proxy.txt', 'w')
tmp.write("")
tmp.close()
tmp1 = open('verified.txt', 'w')
tmp1.write("")
tmp1.close()
# 多线程爬虫西刺代理网,找可用ip
getProxy("http://www.xicidaili.com/nn/")
getProxy("http://www.xicidaili.com/nt/")
getProxy("http://www.xicidaili.com/wn/")
getProxy("http://www.xicidaili.com/wt/")

all_thread = []
for i in range(30):
t = threading.Thread(target=verifyProxyList)
all_thread.append(t)
t.start()

for t in all_thread:
t.join()

inFile.close()
verifiedtxt.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
(代码可以使用,贴出来是为了让大家参考,以后可以修改为自己的。)

运行一下,效果:


爬出来的可用的很少或者很短:

所以这种方式,不推荐。

4.2.2 开源库的ip代理池—异步async-proxy-pool
开源库 async-proxy-pool 是异步爬虫代理池,以 Python asyncio 为基础,旨在充分利用 Python 的异步性能。

异步处理比同步处理能提升成百上千倍的效率。

下载和使用教程:
async-proxy-pool

运行环境

项目使用了 sanic,一个异步网络框架。所以建议运行 Python 环境为 Python3.5+,并且sanic 不支持 Windows 系统,Windows 用户(比如我 smile)可以考虑使用 Ubuntu on Windows。

这我就不开心了,这玩意儿不支持Windows 系统,如果你不是win的。那你可以继续照着他的官网搞。(相信大多数人还是windows,我就不讲了。)

4.2.3 开源 ip代理池—ProxyPool(吐血推荐)
类比线程池,进程池,懂了吧?
这是俺发现的一个不错的开源 ip 代理池ProxyPool,可以用windows系统的,至少Python3.5以上环境哟,还需要将Redis服务开启。

现成的代理池,还不用起来?

ProxyPool下载地址:

https://github.com/Python3WebSpider/ProxyPool.git

(可以手动下载也可以使用git下来。)

1.ProxyPool的使用:

首先使用 git clone 将源代码拉到你本地,

git clone https://github.com/Python3WebSpider/ProxyPool.git
1
2.接着打开项目中的 setting.py,在这里可以配置相关信息,比如 Redis 的地址密码相关。

3.进入proxypool目录,修改settings.py文件,PASSWORD为Redis密码,如果为空,则设置为None。(新装的redis一般没有密码。)

(如果你没 redis 的话,可以先去下载了安装了再来看吧。)

(假设你的redis已经安装完成。)

4.接着在你 clone 下来的文件目录中(就是这个ProxyPool存的电脑路径 )

5.安装相关所需的 依赖包:
(pip或pip3)

pip install -r requirements.txt
1
(如果你把ProxyPool导入在pycharm里面,那就一切都在pycharm里面搞就可以了。)

需要下载的都是:


6.接下来开启你的 redis服务,

直接cmd 打开dos窗口,运行:redis-server.exe
即可开启redis服务器。redis 的默认端口就是 6379


7.接着就可以运行 run.py 了。

可以在cmd里面命令方式运行,也可以导入pycharm里面运行。

图示:


8.运行 run.py 以后,你可以打开你的redis管理工具,或者进入redis里面查看,这时候在你的 redis 中就会存入很多已经爬取到的代理 ip 了:


9.项目跑起来之后,【不要停止】,此时redis里面存了ip,就可以访问这个代理池了。

在上面的图中,可以看到有这么一句话

Running on http://0.0.0.0:5555/ (Press CTRL+C to quit)
这就是告诉我们随机访问地址URL是多少。
10.在浏览器中随机获取一个代理 ip 地址:

你就浏览器输入:

http://0.0.0.0:5555/random

这样访问之后就会获取到一个随机的代理 ip。

图示:


11.在代码中随机获取一个ip代理

就这样:

import requests
# 随机ip代理获取
PROXY_POOL_URL = 'http://localhost:5555/random'
def get_proxy():
try:
response = requests.get(PROXY_POOL_URL)
if response.status_code == 200:
return response.text
except ConnectionError:
return None

if __name__ == '__main__':
print(get_proxy())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
图示:

好了。到此结束了。

使用这个 ip代理池,目前来说是最好的了,又免费又高效唉~~~

5.报错解决
安装的时候,如果报错类似于如下:

AttributeError: ‘int’ object has no attribute 'items

更新一下 对应的xxx软件版本,比如redis 版本:

pip install redis==3.33.1
1
好了,到这里,我们成功的在代理池中获取代理 ip 了,再也不用怕被封ip了,因为我们有很多ip可以用了。

( ^ _ ^ )/~~拜拜
————————————————
版权声明:本文为CSDN博主「csdnzoutao」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ITBigGod/article/details/103248172

猜你喜欢

转载自www.cnblogs.com/1994jinnan/p/11955129.html