Python爬取代理IP

        在一些网页的内容爬取过程中,有时候在单位时间内如果我们发送的请求次数过多,网站就可能会封掉我们的IP地址,这时候为了保证我们的爬虫的正常运行,我们就要使用代理IP。

        下面来介绍如何构建自己的IP池。

我们用快代理来获取代理ip地址:国内高匿免费HTTP代理IP - 快代理

        通过lxml模块的etree,我们很快就可以通过网页源码来获取储存代理ip地址和端口以及IP类型的标签,对它们的爬取也不是一件难事。

        IP爬到后接下来我们要验证我们爬取的IP是否是真正有效的,毕竟作为免费的IP,有效性还是不高的,需要我们进一步的甄别。

在这里我再分享一个网站:

http://icanhazip.com/

        通过访问这个网站,我们可以得到自己当前的IP地址,由此我们可以根据访问该网站得到的返回数据与我们使用的代理IP进行对比观察是否相同,就可以判断我们爬取的代理IP是否有效了。

        下面是完整代码:

import requests
from lxml import etree
import time

headers = {"User-Agent": "mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"}

def get_ips():
    ls = []
    ipps = []
    for i in range(1, 3):
        url = f"https://free.kuaidaili.com/free/inha/{i}/"
        page = requests.get(url=url, headers=headers).text
        tree = etree.HTML(page)
        ips = tree.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')
        for i in ips:
            try:
                ip = "http://" + i.xpath('./td[@data-title="IP"]/text()')[0] + ":" + \
                     i.xpath('./td[@data-title="PORT"]/text()')[0]
                ipps.append(ip)
            except:
                continue
        time.sleep(1)
    ipps = list(set(ipps))
    for ip in ipps:
        dic = {}
        dic["http"] = ip
        ls.append(dic)
    return ls


def check_ips(ls):
    url = 'http://icanhazip.com/'
    for i in ls[::-1]:
        try:
            r = requests.get(url=url, headers=headers, proxies=i,timeout=5)
            r.raise_for_status()
            if r.text[:13]==i['http'][7:20]:
                continue
            else:
                ls.remove(i)
        except:
            ls.remove(i)
    return ls


def ips():
    a=get_ips()
    b=check_ips(a)
    return b


if __name__ == '__main__':
    print(ips())

        上述代码我仅爬取快代理网站的前两页IP内容,如需更多,可更改get_ips()函数第一个for循环的次数。但是这种方法也有一个弊端,我是一页一页的爬取,然后把爬取的代理IP一个一个的判断,速度会慢下来不少。为了更高效的爬取,我们可以导入线程池,在爬取和验证的过程中均导入线程池,可以让我们爬取的速度成倍增长。

import requests
from lxml import etree
from multiprocessing.dummy import Pool

headers = {"User-Agent": "mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"}
ls=[]
ipps=[]

def get_ips(a):
    url = f"https://free.kuaidaili.com/free/inha/{a}/"
    page = requests.get(url=url, headers=headers).text
    tree = etree.HTML(page)
    ips = tree.xpath('//table[@class="table table-bordered table-striped"]/tbody/tr')
    for i in ips:
        try:
            ip = "http://" + i.xpath('./td[@data-title="IP"]/text()')[0] + ":" + \
                 i.xpath('./td[@data-title="PORT"]/text()')[0]
            ipps.append(ip)
        except:
            continue


pool_1=Pool(2)
pool_1.map(get_ips,list(range(1,3)))
pool_1.close()
pool_1.join()

for ip in list(set(ipps)):
    dic={}
    dic['http']=ip
    ls.append(dic)
print(len(ls))

def check_ips(i):
    url = 'http://icanhazip.com/'
    try:
        r = requests.get(url=url, headers=headers, proxies=i,timeout=5)
        r.raise_for_status()
        if r.text[:13]==i['http'][7:20]:
            pass
        else:
            ls.remove(i)
    except:
        ls.remove(i)


pool_2=Pool(15)
pool_2.map(check_ips,ls)
pool_2.close()
pool_2.join()

if __name__ == '__main__':
    print(ls)

爬取前两页的代理IP,可以发现,基本上每5个代理IP中仅有1个是有用的,但毕竟这是免费的,我们仅仅是增加了一步验证的过程,总的来说,还是非常不错的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值