爬虫1_自建代理IP池

从今天起,开始一点点记录自己学习的路线,也是作为对自己的一个监督。
今天要做的是从西刺代理网(https://www.xicidaili.com/nn/)爬取免费代理ip存入本地redis。
作为一个不舍得花钱买动态代理ip的穷鬼,只能想出这么个鬼办法了。

获取url

在这里插入图片描述
上图为西刺代理网的第二页,我们往后翻几页可以很容易地分析出,西刺url设计的很简单,翻页的变化就在于/nn/后面的数字变化,所以可以确定的是url = f"https://www.xicidaili.com/nn/{page}",这里的page就是列表页的序号,下面代码我用的是format方式进行url的拼接。

def main():
    xc = XiCi()
    basic_url = "https://www.xicidaili.com/nn/{}"
    for page in range(1, 15):
        url = basic_url.format(page)
        xc.get_page(url)

分析页面的源码

在这里插入图片描述

  • 通过F12查看渲染后的代码和Ctrl+U查看源码发现两者没有区别,所以可以判断西刺没有做什么加密反爬虫,什么js动态调用数据的事儿所以就方便我们做坏事爬取代理。
  • 我们可以发现整个页面的代理ip列表其实就是放在一个tbody标签里面,里面有一堆的tr,要注意,第一个tr是表头,不是我们要爬取的ip地址,所以我们xpath可以这样写//tr[position()>1]
  • 打开一个tr我们可以看到,西刺真的是特别好,写的干干净净,host在td[2],port在td[3],协议在td[6]。
    在这里插入图片描述

完整代码

"""
爬取西刺网的免费代理ip,并进行测试,存入redis
"""
import redis
import requests
from fake_useragent import UserAgent
from gevent.threadpool import ThreadPoolExecutor
from lxml import etree


class XiCi(object):
    def __init__(self):
        """
        类加载的一些初始化设置,包括连接redis,创建线程池等
        """
        self.conn = redis.StrictRedis(host="localhost", port=6379, db=1)  # 初始化连接redis
        self.threadpool = ThreadPoolExecutor(max_workers=100)  # 此处使用线程池
        self.HTTP_PROXY = 'http_proxy'  # 用于存放http代理
        self.HTTPS_PROXY = 'https_proxy'  # 用于存放https代理
        self.count = 0  # 用来计数已经存入几个代理ip
        self.test_url = "https://www.baidu.com"

    def get_page(self, url):
        """
        获取每个详情列表的tr,传入parse进行解析ip,存入redis
        :param url:
        :return:
        """
        headers = {
            "User-Agent": UserAgent().random,
        }
        res = requests.get(url=url, headers=headers)
        html = etree.HTML(res.text)
        tr_s = html.xpath("//tr[position()>1]")  # 这里返回的是一个列表,里面是100个tr
        self.threadpool.map(self._parse_proxy, tr_s)

    def _parse_proxy(self, tr):
        """
        获取每一条tr,对http,ip,port进行解析,将三者拼接再进行测试
        将http和https分别存在两个不同的set里面
        因为是set所以也直接避免了重复问题
        :param tr:
        :return:
        """
        host = tr.xpath("./td[2]/text()")[0]
        port = tr.xpath("./td[3]/text()")[0]
        type = tr.xpath("./td[6]/text()")[0].lower()
        if type == "http":
            proxy = "http://" + host + ":" + port
            self._test_proxy(type, proxy)
        else:
            proxy = "https://" + host + ":" + port
            self._test_proxy(type, proxy)

    def _test_proxy(self, type, proxy):
        """
        测试代理ip是否可用
        :param proxy:
        :return:
        """
        proxies = {
            type: proxy,
        }
        try:
            res = requests.get(url=self.test_url, proxies=proxies, timeout=5)
            # 如果返回值是200说明访问成功,根据type进行区分,存入不同的set
            if res.status_code == 200:
                if type == 'http':
                    self.conn.sadd(self.HTTP_PROXY, proxy)
                else:
                    self.conn.sadd(self.HTTPS_PROXY, proxy)
                self.count += 1
                print(f"\r已加载{self.count}个proxy", end="")
        except Exception as e:
            print(f"\r无效ip:{proxy}", end="")


def main():
    xc = XiCi()
    basic_url = "https://www.xicidaili.com/nn/{}"
    for page in range(1, 5):
        url = basic_url.format(page)
        xc.get_page(url)


if __name__ == '__main__':
    main()

总结

  • 免费的代理ip基本来回就这几个,很容易被别的网站封了,所以也就是拿来学习。
  • 本次使用到的几个知识点是:
    – requests
    – redis
    – fake_useragent
    – gevent.threadpool
    – lxml
  • 写的不好还请各位海涵,欢迎各位底下留言批评。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值