爬虫代理池——搭建IP代理池

构建可靠的代理池服务,为数以千计的爬虫提供高效代理,确保每个爬虫都收到对应网站的正确代理IP,在公司内部进行分布式深网爬虫,保证爬虫快速可靠。 当然,公司内部的产品不能为了功能而开源。 但是在闲暇时间,我手痒痒,想利用一些开源工具来创建一个简单的代理池服务。

如何解决IP阻塞问题?

有以下几种方法:

  • 更改请求头模仿浏览器(而不是直接访问代码)访问
  • 使用代理并旋转它们
  • 配置访问间隔

获取代理的IP地址

  • 购买一个网站:做研究
  • 检查 -> 鼠标位置:
  • 代码如下,将要获取的代理IP地址存放在proxy ip列表中。 它是 class = “odd” 标签内容的一部分。

from bs4 import BeautifulSoup

import requests

import time

def open_proxy_url(url):

    user_agent = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36’

    headers = {

    ‘User-Agent’: user_agent}

    try:

        r = requests.get(url, headers = headers, timeout = 20)

        r.raise_for_status()

        r.encoding = r.apparent_encoding

        return(r.text)

    except:

        print(‘无法访问网页’ + url)

def get_proxy_ip(response):

    proxy_ip_list = []

    soup = BeautifulSoup(response, ‘html.parser’)

    proxy_ips  = soup.select(‘.odd’)#选择标签

    for proxy_ip in proxy_ips:

        ip = proxy_ip.select(‘td’)[1].text

        port = proxy_ip.select(‘td’)[2].text

        protocol = proxy_ip.select(‘td’)[5].text

        if protocol in (‘HTTP’,’HTTPS’):

            proxy_ip_list.append(f'{protocol}://{ip}:{port}’)

    return proxy_ip_list

if __name__ == ‘__main__’:

    proxy_url = ‘https://www.xicidaili.com/’

    text = open_proxy_url(proxy_url)

    proxy_ip_filename = ‘proxy_ip.txt’

    with open(proxy_ip_filename, ‘w’) as f:

        f.write(text)

    text = open(proxy_ip_filename, ‘r’).read()

    proxy_ip_list = get_proxy_ip(text)

    print(proxy_ip_list)

[‘HTTPS://183.195.106.118:8118’, ‘HTTPS://223.68.190.130:8181’, ‘HTTPS://110.189.152.86:52277’, ‘HTTPS://27.184.157.205:8118’, ‘HTTP://202.107.233.123:8090’, ‘HTTP://211.159.219.225:8118’, ‘HTTPS://115.29.108.117:8118’, ‘HTTPS://183.250.255.86:63000’, ‘HTTP://111.222.141.127:8118’, ‘HTTP://117.94.213.119:8118’, ‘HTTPS://125.123.139.19:9000’, ‘HTTP://122.225.45.66:43391’, ‘HTTP://163.125.113.249:8088’, ‘HTTP://14.20.235.73:808’, ‘HTTP://123.163.24.113:3128’, 

获取以下信息:

获取到代理IP地址后,发现少了很多信息。 仔细查看元素,发现有些元素不是class=”odd”,但是…,这些数据不是用class=”odd”的结果得到的,odd,但是没有class=”odd” ,, “是偶数的结果。

使用 bs4 的 find all(‘tr’) 查找所有 IP 地址:

def get_proxy_ip(response):

    proxy_ip_list = []

    soup = BeautifulSoup(response, ‘html.parser’)

    proxy_ips = soup.find(id = ‘ip_list’).find_all(‘tr’)

    for proxy_ip in proxy_ips:

        if len(proxy_ip.select(‘td’)) >=8:

            ip = proxy_ip.select(‘td’)[1].text

            port = proxy_ip.select(‘td’)[2].text

            protocol = proxy_ip.select(‘td’)[5].text

            if protocol in (‘HTTP’,’HTTPS’,’http’,’https’):

                proxy_ip_list.append(f'{protocol}://{ip}:{port}’)

    return proxy_ip_list

使用代理

  • 代理采用字典格式:
  • {‘http’: ‘http://IP:port’,’https’:’https://IP:port’}
  • 只需将它传递到 requests get 方法中。
  • web_data = requests.get
  • (url, headers=headers, proxies=proxies)

def open_url_using_proxy(url, proxy):

    user_agent = ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36’

    headers = {

    ‘User-Agent’: user_agent}

    proxies = {

    }

    if proxy.startswith((‘HTTPS’,’https’)):

        proxies[‘https’] = proxy

    else:

        proxies[‘http’] = proxy

    try:

        r = requests.get(url, headers = headers, proxies = proxies, timeout = 10)

        r.raise_for_status()

        r.encoding = r.apparent_encoding

        return (r.text, r.status_code)

    except:

        print(‘无法访问网页’ + url)

        print(‘无效代理IP: ‘ + proxy)

        return False

验证代理 IP 地址的真实性

我们应该确认一下代理IP地址真实性。 一旦有效,将其添加到我们的代理 IP 地址池中。 使用的技术如下: 访问该网站以接收 200 返回码。 亲自访问一些网站,查看标题等,确保标题与您的预期相符。 通过访问各种可以返回所访问IP的网站,如“查询我的IP”网站,查看返回的IP地址。 检查返回代码。

def check_proxy_avaliability(proxy):

    url = ‘http://www.baidu.com’

    result = open_url_using_proxy(url, proxy)

    VALID_PROXY = False

    if result:

        text, status_code = result

        if status_code == 200:

            print(‘有效代理IP: ‘ + proxy)

        else:

            print(‘无效代理IP: ‘ + proxy)

增强功能:验证网站的标题

def check_proxy_avaliability(proxy):

    url = ‘http://www.baidu.com’

    text, status_code = open_url_using_proxy(url, proxy)

    VALID = False

    if status_code == 200:

        if r_title:

            if r_title[0] == ‘<title>百度一下,你就知道</title>’:

                VALID = True

    if VALID:

        print(‘有效代理IP: ‘ + proxy)

    else:

        print(‘无效代理IP: ‘ + proxy)

关于 HTTP 和 HTTPS 代理

  • 如您所见,代理有两个键值对:
  • “http”: “http://IP:端口” “https”: “https://IP:端口”
  • 其中之一是 HTTP 代理,它只适用于 HTTP 网站,对 HTTPS 网站使用本地 IP,反之亦然。
  • 由于我刚刚使用的验证域是https://jsonip.com,如果找到合法代理,则为HTTPS网站,如果是HTTPS代理,则返回代理地址。
  • 如果它是 HTTP 代理,它将通过本地 IP 访问并返回我的公共 IP 地址。