每周一练:如何创建自己的Python爬虫代理IP池(免费IP)

学习Python爬虫的同学,都需要自己建造一个代理IP池(免费的),下面给大家分享代理IP池如何建池。

本项目爬取的是代理商提供的免费IP。

项目爬取代理IP商列表:(自己练手增加代理商)

  1. 快代理
  2. 89免费代理
  3. 高可用全球免费代理IP库

项目环境

  • Python 3.9

  • selenium 4.1.3

  • chromedriver 100.0.4896.60 (需要适配本电脑chrome版本) 下载G

Git仓库

爬取流程:

1、通过命令输入获取爬取网站的选择

main.py

在命令输入选项,获取选择爬取网站,如果全部网站爬取,用多线程的方式进行处理。

异常处理,用于输入有误时,重复执行 run() 方法。

def run():

    try:
        print('''请选择获取的ip提供商:
    1. 快代理
    2. 89免费代理 
    3. 高可用全球免费代理ip库
    4. 全部''')
        channel = input('请输入选项(数字):')
        if channel == '1':
            Kuaidaili().run()
        elif channel == '2':
            IpFree().run()
        elif channel == '3':
            JiangXianLi().run()
        elif channel == '4':
            # 多线程处理
            channels = [
                Kuaidaili().run,
                IpFree().run,
                JiangXianLi().run
            ]
            # 创建线程
            threads = []
            for i in channels:
                threads.append(threading.Thread(target=i))
            # 启动线程
            for i in threads:
                i.start()
            # 等待线程结束
            for i in threads:
                i.join()

        else:
            raise Exception('输入错误!')
    except Exception as e:
        print('输入错误,请重新输入!')
        run()

2、爬虫主流程

spider_base.py 一般爬虫的处理流程分为三个步骤:

  1. 爬取数据,
  2. 整理清洗数据,
  3. 数据保存展示。

由于我们爬取的IP是公开,很多已经过期不能使用我们需要爬取的是当前可以使用的IP,故此需要进行IP的校验检查,我们就在数据清理后增加 “检查数据”

    # 爬取流程
    def run(self):
        # 爬取数据
        html = self.spider()
        # 整理数据
        data = self.pipeline(html)
        # 检查数据
        data = self.check_useful(data)
        # 保存数据
        self.save(data)

3、requests和selenium爬取类定义不同爬取方法

不同的网站,我们需要使用不同的爬取方式,非异步加载的网站,我们采用的是requests包进行爬取即可,异步或者反爬处理过的网站,我们使用selenium爬取。

spider_requests.py 

爬取需要注意编码问题,如果乱码,需要增加:req.encoding = req.apparent_encoding

    # 爬取数据
    def spider(self):
        req = requests.get(url=self.base_url, headers=Proxy().get_header(), timeout=5)
        # 编码处理
        req.encoding = req.apparent_encoding

        return req.text

spider_selenium.py

使用selenium,需要注意 chromedriver 和 chrome版本的问题。

注意:chrome_options.add_argument('--headless')  配置后不打开chrome窗口,建议打开进行调试。

    # 爬取数据
    def spider(self):

        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument('--headless')
        browser = webdriver.Chrome(options=chrome_options)
        browser.get(url=self.base_url)
        # 编码处理
        data = browser.page_source
        browser.quit()
        return data

4、不同代理商网站的爬取类

channels 目录下定义不同的爬取渠道

每一个爬取渠道的配置不一样的爬取地址和方法,如需要进行不同的数据清理,可以在该类重新定义。

# !/usr/bin/python
# -*- coding: utf-8 -*-
"""
@File    :  kuaidaili.py
@Time    :  2022/4/16 18:24
@Author  :  Mz100
@Desc    :  None
"""
import pandas as pd

from libs.spider_selenium import Spider


class Kuaidaili(Spider):

    def __init__(self):
        self.base_url = "https://www.kuaidaili.com/free/"
        self.source = 2
        
    # 数据整理
    def pipeline(self, html):

        tables = pd.read_html(html)
        table = tables[0]
        sources = []
        isps = []
        for i in table['位置']:
            sources.append(self.source)
            isps.append(i.split()[-1])
        # 创建 DataFrame
        df = pd.DataFrame()
        df['ip'] = table['IP']
        df['port'] = table['PORT']
        df['address'] = table['位置']
        df['isp'] = isps
        df['source'] = sources

        return df

 5、最后通过Sqlite保存IP数据

# 数据存储
    def save(self, df):
        conn = sqlite3.connect(Sqlite().get_db_file())
        c = conn.cursor()
        if df.values.all():
            for i in df.values:
                if str(i[1]).isdigit():
                    try:
                        sql = "INSERT INTO {5} (ip,port,address,isp,source) VALUES ('{0}', '{1}', '{2}', '{3}','{4}')" \
                            .format(i[0], i[1], i[2], i[3], i[4], Sqlite().get_table())
                        c.execute(sql)
                        conn.commit()
                        print('脚本:' + sql + '插入成功')
                    except Exception as e:
                        print('脚本:' + sql + '插入失败')
                        print(e)
        conn.close()

至此,我们实现了 代理IP池的建池开发。

喜欢的点个赞 ❤ 吧!

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mokyzone

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值