python爬虫之搭建代理池

实验目的

  在利用爬虫爬取我们想要的信息时,往往会遇到一些反爬虫能力很强的网站,返回状态码403Forbidden或是提醒我们”您的IP访问频率太高”,需要我们输入验证码或是直接封了当前IP。遇到这种情况,使用代理IP是一个不错的选择,利用代理IP发起请求,而不用影响我们的真实IP。所以,搭建一个代理池,存放一些可用的代理IP是利用爬虫的过程中非常有效的一个手段。

实验环境

MongoDB
python3
主要用到requests、pyquery、pymongo库

爬取分析

  本实验搭建的代理池,其代理IP都是一些免费的高匿代理,所以会有时效性,需要在使用时进行生命验证并进行更新。

  搭建代理池主要分成三个部分:
1.获取代理IP
从一些代理网站抓取免费的高匿代理,代理的形式都是IP+端口。
2.验证可用性
检测代理的可用性。可以设置一个检测链接,最好是爬取哪个网站就用哪个网站进行检测,也可以直接用百度等网站进行测试。
3.存储到数据库
利用mongo数据库,存储抓取下来的可用代理。

实验过程

代理获取

  主要从一些免费的代理网站获取代理IP,比如西刺66代理等网站都可以抓取。
解析代理网站,获取代理ip,这里以西刺为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def parse_url(url):
headers = [
{'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0'},
{'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'},
{'User-Agent': 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11'},
{'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'},
{'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:40.0) Gecko/20100101 Firefox/40.0'},
{'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/44.0.2403.89 Chrome/44.0.2403.89 Safari/537.36'}
]
try:
response = requests.get(url,headers=random.choice(headers))
if response.status_code == 200:
return response.text
except ConnectionError:
print('Error')

  观察页面,可以看到有翻页操作,找到相关元素:

  获取总页数,并通过构造URL:’http://www.xicidaili.com/nn/{}'.format(page) 实现翻页。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def proxy_xici():
url = 'http://www.xicidaili.com/nn'
response = parse_url(url)
doc = pq(response)

total_page = doc.find('.pagination a').eq(-2).text()
proxies = []
for page in range(1,int(total_page)+1):
url = 'http://www.xicidaili.com/nn/{}'.format(page)
doc = pq(parse_url(url))
trs = doc.find('table#ip_list tr').items()
for tr in trs:
if tr == doc.find('table#ip_list tr').eq(0):
continue
ip = tr.find('td').eq(1).text()
port = tr.find('td').eq(2).text()
#proxy = ip+':'+port
proxy = {
'ip':ip,
'port':port
}
proxies.append(proxy)
return proxies

  用pyquery解析每一页,在ip_list里提取每一个代理的IP和PORT,写入字典并存进列表里。

代理验证

  抓取到每页的代理IP和端口号后,我们用百度进行验证,如果返回的状态码是200,且间隔时间小于10秒,则认为该代理是有效的:

1
2
3
4
5
6
7
8
9
def proxy_test(proxy):
try:
resp = requests.get(TEST_URL, proxies={'http': 'http://{0}:{1}'.format(proxy['ip'], proxy['port']),
'https': 'https://{0}:{1}'.format(proxy['ip'], proxy['port'])}, timeout=10)
if resp and resp.status_code == 200:
#collection.insert_one(proxy)
print('Valid proxy', proxy)
except Exception as e:
pass

数据库存储

  本实验采用的是mongo数据库,将所有通过验证的代理存储到数据库中:

1
2
3
4
5
client = MongoClient("localhost",27017)
db = client.proxies
collection = db['Proxy_Port']

collection.insert(proxy)

实验结果与说明

完整代码见ProxyPool.py

运行完整代码,结果如下:

1
python ProxyPool.py

查看proxies数据库里的Proxy_Port表,存放的部分内容如下: