获取免费的开源代理,并进行筛选
最近用Python爬数据需要用到了代理,发现网上很多免费的代理都不能用,于是对代理进行了筛选,挑选出较快的代理。
1 获取免费代理
首选先获取大量的代理来用于筛选。开始搜索了一下代理,发现西刺代理、快代理很多不能用(可能是用的人太多了),最后找到了github的开源代理,发现还可以。传送门:github的开源代理。
防止频繁访问开源代理的网站,我们把代理数据爬下来,保存在本地文本当中,下次要获取时,直接读取本地文本即可。我们用python的requests来爬取数据,requests这个库简直是神一般的存在,写出这个库的人简直是天使好嘛(好了好了跑偏了)。主要思路是:用requests来GET网页,开源的代理网页很方便进行json解析,直接解析获取想要的数据。代码如下:
import requests
import re,json,os
def save_ips(isCover=False):
"""保存所有代理IP的数据"""
url = "https://raw.githubusercontent.com/fate0/proxylist/master/proxy.list"# github上的开源IP
r = requests.get(url)
wb = r.text
# 处理数据
proxies = []
pattern = re.compile(r'{.*?}')
data = pattern.findall(wb, re.S)
for d in data:
dict_obj = json.loads(d)
if dict_obj["anonymity"] == "high_anonymous": # 这里我只保存了高匿代理
temp = {}
temp["type"] = dict_obj["type"]
temp["host"] = dict_obj["host"]
temp["port"] = dict_obj["port"]
proxies.append(temp)
# 把代理IP保存下来
filename = "all_ips.txt"
path = filename # 保存文件的路径,这里我直接保存在项目的路径下了
if isCover == False: # 防止覆盖原有的文件
if os.path.exists(path):
print(path,"文件已存在,注意防止覆盖无关文件")
return
f = open(path, "w")
f.write(json.dumps(proxies)) # 以json格式保存数据,方便解析
f.close()
print(path,'save succeed')
2 初步筛选
这样就获取了大量的免费代理了,然后进行筛选。初步筛思路是用代理向网站发送GET请求,挑选出请求成功的代理,配合多进程食用加快筛选速度。
先解析本地的all_ips.txt文档,获得 { “http” : http_proxy , “https” : https_proxy} 的格式的代理。其中http_proxy的代理对应的是使用HTTP协议的网站,https_proxy的代理是对应使用HTTPS协议的网站。代码如下:
import os,random
def get_ips(total=1):
"""读取已经保存的IP,随机抽出total数量的IP"""
path = "all_ips.txt"
if os.path.exists(path) == False:
print(path,"文件不存在")
return
f = open(path,'r')
data = json.load(f)
f.close()
http_list = []
https_list = []
for i in range(len(data)):
if data[i]['type'] == 'http':
http_list.append('http://' + data[i]['host'] + ':' + str(data[i]['port']))
if data[i]['type'] == 'https':
https_list.append('https://' + data[i]['host'] + ':' + str(data[i]['port']))
proxies = []
for j in range(total):
http = random.choice(http_list)
https = random.choice(https_list)
proxy = {'http':http,'https':https} # 返回的每一个代理
proxies.append(proxy)
return proxies
配合多进程来筛选可用的代理IP,这里从all_ips.txt中取出100个代理,筛选出访问url较快的IP,然后保存在screened_ips.txt文件中。代码如下:
from multiprocessing import Pool
import requests
import time,json
import save_ips,get_ips
def my_process(proxies):
"""每个子进程"""
useful_proxies = []
url = "" # 要用代理访问的url
headers = {
"Cookies":"",
"User-Agent":"",
} # 请求头,cookies,UA都写在请求头里
timeout = 2 # 超时设置,可以用来控制代理的速度,像设置为1可以挑选更快的代理
for proxy in proxies:
try:
r = requests.get(url=url,headers=headers,proxies=proxy,timeout=timeout)
useful_proxies.append(proxy)
except:
continue
return useful_proxies
if __name__ == "__main__":
s = time.time()
# 保存所有的IP
save_ips(isCover=True)
# 多进程筛选较快的IP
data = []
pool = Pool(4)
result = []
for i in range(10):
proxies = get_ips(total=10)
useful_proxies = pool.apply_async(my_process,args=(proxies,))
result.append(useful_proxies)
pool.close()
pool.join()
# 将较快的代理保存在data数组中,写入文件
for r in result:
for proxy in r.get():
data.append(proxy)
path = "screened_ips.txt" # 保存经过初步筛选的代理IP的文件路径
f = open(path,"w")
f.write(json.dumps(data))
f.close()
print("useful ips save succeed")
e = time.time()
print("总时间",e-s)
3 多次筛选
经过初步筛选,这些代理能用于项目当中了,但是这些代理是不稳定的,也许初步筛选的时候能用,到项目中却不能使用是正常的情况。对此,我是用python的try-except来处理的。大致的思路如下:
import json,random
import requests
path = "screened_ips.txt"
f = open(path,"r")
ips = json.load(f) # 经过初步筛选的IP
f.close()
ip = ips[0] # 保存当前代理的变量
def get_request():
url = ""
headers = {}
timeout = 5
while True:
try:
proxy = ip # 用当前的代理去发送GET请求
r = requests.get(url=url,headers=headers,proxies=proxy,timeout=timeout)
print("request succeed")
return
except:
ip = random.choice(ips)# 原代理挂掉了,通过改变ip的值来改变当前代理,继续发送GET请求
continue
用try-except,这样能防止因为代理挂了导致程序运行终止,在except块中可以对挂掉的代理进行统计,运行结束后打印出来。对于多次挂掉的代理,在screened_ips.txt中删去,这样多次筛选,得到更好更快的代理。
4 后话
经过前面的筛选,得到了更快的代理。对于爬虫的话,多个cookie+多个代理 可以提高抓取数据的效率,但是在使用代理时也考虑一下对方服务器的压力,控制到爬取的速度,别频繁的访问对方的服务器。有句歌词怎么唱来着“向前一步是黄昏,退后一步人生”~~哈哈哈
关于完整的代码我放在github上了:源码