Python_爬虫_代理池

文章未经允许,不可转载

阅读本文需要Python基础,MongoDB基础。如果你是一名正在学习爬虫的Pythoner,相信本文会很有帮助,:)
如果没有这些基础,建议看看我的另一篇文章Python-数据存储,应该会所帮助

写在前面

Oh, My God! 爬取被限制了 >_<。加User-Agent了么?是不是要Cookie?或许更改一下IP呢?
是的,这篇文章就来讲讲怎么构建一个代理池,但是只讲一种很简单的实现方式,如果你有更好的方式,欢迎投稿
Done is better than perfect!

代理IP的来源

  • 免费
    • google一下,有很多这样的网站比如http://www.xicidaili.com/
    • 写一个爬虫,把这些代理都爬取下来,构建一个代理池
    • IP质量堪忧
  • 付费
    • 贵的
      • 没有用过,>_<
    • 便宜的
      • 提供了接口,直接调用接口就可以得到IP
      • IP质量也堪忧,只不过比免费的好点,至少量大一点
      • 关键是需要校验是否为高匿,虽然网站写的是高匿,实际上得到的IP是高匿的,很少

便宜的代理IP,我习惯性获取的是高匿且为HTTPS的IP

构建代理池思路

其实道理很简单的,分为两步

  • 获取IP,存放到数据库中
  • 检查IP是否符合要求,把符合要求的IP存储到数据库中

两步真的够吗?不够,因为代理IP会失效,那么需要增加一个更新IP的行为

定义触发更新的行为

获得了一批有效的IP,也明白这批IP不会永远有效,那么什么时候更新/换这批IP,让新的有效IP补充进来呢?

可以监测有效IP的个数,如果降低到某个值,更新程序启动

但是不考虑这门复杂的,简单粗暴点,直接确定10分钟启动一次更新程序,当然也可以是20分钟等

总结一下要做的事情

从网上得到高匿IP,检查是否高匿,每10分钟更换一次IP,保持代理池中的IP一直有效

获取IP且检查高匿

高匿代理的获取方式,需要自己去探索了,用免费的或者用付费的,不做任何推荐哈。我本身只用过很便宜的那种,<_<

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
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import re

import requests
import pymongo
# from multiprocessing import Pool

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0'}
TEST_URL = 'https://icanhazip.com/'


# 用数据库存储从网站上获取的所有ip和检测后的有效ip
client = pymongo.MongoClient('localhost', 27017)
db = client['proxy_ip']
all_ip_col = db['all_ip'] # 所有ip
valid_ip_col = db['valid_ip'] # 有效ip


# 得到网上的ip
def get_internet_ip():

ip_list = buy_or_not_buy() # ip均要包含端口 比如 10.10.10.10:8888

for ip in ip_list: # ip_list获取,每个人使用的方式不同
data = {'proxy': 'http://'+ip} # 组装ip
all_ip_col.insert_one(data)

# 整理所有将要被校验的ip
def get_all_ip():
all_ip_list = []

get_internet_ip()

for document in valid_ip_col.find(): # 为了避免浪费,现在还有效的ip也加入到all_ip_list中
all_ip_list.append(document['proxy'])

for document in all_ip_col.find(): # 刚刚得到的新ip存到all_ip_list
all_ip_list.append(document['proxy'])

return all_ip_list

def check_valid(check_ip):
ip_pattern = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

proxy_dict = {'https': check_ip} # 组成requests需要的形式

try:
# 如果访问,没有报错(800ms内),访问速度还行
web_data = requests.get(TEST_URL, timeout=0.8, headers=headers, proxies=proxy_dict)

# 检查是否高匿
# 如果icanhazip.com返回的ip是使用的代理ip(check_ip),证明是高匿
if re.search(ip_pattern, web_data.text).group() == re.search(ip_pattern, check_ip).group():
valid_ip_data = {'proxy': check_ip}
valid_ip_col.insert_one(valid_ip_data)
except Exception as e:
print('error: {0}\nip:{1}'.format(e, check_ip))


if __name__ == '__main__':

all_ip_col.remove() # 将存放所有ip的集合清除掉

all_ip_list = get_all_ip() # 得到所有待检测的ip,包括刚刚从网上得到的ip和valid_ip_col中的ip

valid_ip_col.remove() # 清除所有valid_ip_col的ip

# 检验ip,将有效ip存放到valid_ip_col
for ip in all_ip_list:
check_valid(ip)

'''
# 多进程进行ip校验,这样更实用
pool = Pool()
pool.map(check_valid, all_ip_list)
pool.close()
pool.join()
'''

实际怎么使用这些高匿代理

仅仅写一个示意代码,可以结合实际问题改编

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
# -*- coding: utf-8 -*-
__author__ = 'duohappy'

import random

import pymongo
import requests

client = pymongo.MongoClient('localhost', 27017)
proxy_db = client['proxy_ip'] # 代理池数据库
valid_ip_col = proxy_db['valid_ip'] # 有效代理集合

# 从数据库中读取ip
def get_proxy_dict():
valid_ip_list = []
for document in valid_ip_col.find():
valid_ip_list.append(document['proxy'])

# 随机构建一个符合requests要求的代理
proxy_dict = {'https': random.choice(valid_ip_list)} if valid_ip_list else None

return proxy_dict

def get_info_from(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"
}

web_data = requests.get(url, headers=headers, proxies=get_proxy_dict())

'''
省略
'''

定时任务

如果每10分钟,运行一次上面的代码,那么是不是实现了代理池的更新呢?

是的!

那么就10分钟运行一次不就好了么

  • Windows
    • 任务计划程序
  • Linux
    • crontab

写在后面

简单的代理池实现思路,不用考虑太多的逻辑,花很短的时间就可以搭一个不那么难用的,:)

您的支持将鼓励我继续创作!