用Python获取免费的开源代理,并筛选出较快的代理

获取免费的开源代理,并进行筛选

最近用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上了:源码

猜你喜欢

转载自blog.csdn.net/weixin_39767528/article/details/82318950
今日推荐