大家好,我是小小明,今天我计划搭建一个代理IP池,采集一些公开的免费的代理IP,放入缓存池中。

要搭建一个代理ip池,我的思路:

  1. 爬虫定期爬取代理IP,验证代理iP有效性,有效则存入Redis数据库
  2. 一个线程或进程定期检查代理ip池的有效性,无效则从中删除

虽然不如直接购买付费的代理IP好用,但是以此训练一下相关技术能力。

本文的目标是至少演示如下技术:

  1. pandas超简代码带请求头解析表格
  2. 查看访问IP的方法
  3. 搭建简易检验代理Ip的网站
  4. Redis数据库的基本操作
  5. 代理ip在request库中的使用方法
  6. Timer定时器的使用
  7. Redis 图形化工具的使用介绍

代理IP的爬取与解析

下面,首先去选择几个免费代理ip的网址去爬一下,百度一下代理ip关键字能够查到很多网站。

这里我选择崔老师书中推荐的一个代理网站进行测试,它提供了高匿代理和普通代理两个页面。

爬取高匿测试一下:

import requests
import pandas as pdheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36'
}i = 1
url = f'https://www.kuaidaili.com/free/inha/{i}/'
r = requests.get(url, headers=headers)
r.encoding = 'u8'
ip_df, = pd.read_html(r.text)
ip_df

代理IP爬了,但是是否真的能用呢?

代理IP的校验

我们需要验证一下,有个不错的测试网站是httpbin.org,我们可以通过它来读取自己的ip地址:

r = requests.get(f"http://httpbin.org/ip")
r.json()

结果大致形式:

{'origin': '116.xx.xx.xxx'}

然后以如下形式访问代理ip:

r = requests.get(f"http://httpbin.org/ip",proxies={'http': "175.42.158.226:9999"})
r.json()

若抛出异常:

说明代理失效。

在我们的机器有公网IP时,我们也可以搭建自己的服务器用于校验代理IP有效性,flask代码:

from flask import *app = Flask(__name__)@app.route('/')
def index():return request.remote_addrif __name__ == '__main__':app.run(host="0.0.0.0", port=8088)

基于此我们可以写一个校验代理IP的方法:

def proxie_ip_validity_check(proxie_ip, proxie_type='http', timeout=1):try:r = requests.get(f"{proxie_type}://httpbin.org/ip", headers=headers,proxies={proxie_type: proxie_ip}, timeout=timeout)if r.status_code == 200:return Truereturn Falseexcept Exception as e:return False

经过我个人测试,高匿代理似乎没有一个是可以用的,所以这次我们只爬取普通代理ip。

批量爬取普通代理ip

设置超时时间为2秒,取7页数据:

import requests
import pandas as pdheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36'
}http_ip_pool = []
https_ip_pool = []
for page in range(1, 8):print("当前爬取页面数:", page)url = f'https://www.kuaidaili.com/free/intr/{page}'r = requests.get(url, headers=headers)r.encoding = 'u8'ip_df, = pd.read_html(r.text)for ip, port, proxie_type in ip_df[["IP", "PORT", "类型"]].values:pool = http_ip_pool if proxie_type.lower() == 'http' else https_ip_poolproxie_ip = f"{ip}:{port}"if proxie_ip_validity_check(proxie_ip, proxie_type.lower(), 2):pool.append(proxie_ip)
len(http_ip_pool), len(https_ip_pool)

经测试爬到26个有效的代理ip,全部都是http类型:

写入到Redis服务器

为了方便其他爬虫程序使用,我们将爬到的代理IP写入到Redis数据库中。

首先需要安装Redis,下载地址:https://github.com/MicrosoftArchive/redis/releases

我的是Windows平台选择了:https://github.com/microsoftarchive/redis/releases/download/win-3.0.504/Redis-x64-3.0.504.zip

解压后直接双击redis-server.exe即可启动Redis服务器:

安装让Python操作redis的库:

pip install redis

基本使用:

import redisr = redis.Redis(host='192.168.3.31', port=6379, db=0)
r.set('name', 'zhangsan')  # 添加
print(r.get('name'))
b'zhangsan'

考虑将代理IP存入Redis的set集合中,因为可以自动去重,测试一下:

r.sadd("proxie_ip", "ip1", "ip2")
r.sadd("proxie_ip", "ip2", "ip3")
r.smembers("proxie_ip")
{b'ip1', b'ip2', b'ip3'}

于是我们可以通过以下命令一次性存入Redis中:

if len(http_ip_pool)>0:r.sadd("proxie_ip_http", *http_ip_pool)
if len(https_ip_pool)>0:r.sadd("proxie_ip_https", *https_ip_pool)

存入Redis数据库后,Redis就已经相当于一个代理IP池,下面我们另外启动一个尝试,常识使用这些代理IP:

从代理IP池中获取代理IP并使用

读取代理IP:

import rediswith redis.Redis(host='192.168.3.31', port=6379, db=0) as r:http_ip_bytes = r.smembers("proxie_ip_http")http_ip_pool = list(map(bytes.decode, http_ip_bytes))
http_ip_pool
['139.9.25.69:3128','119.3.235.101:3128','122.51.207.244:8888','106.58.191.24:8888','222.74.202.229:9999','47.111.71.29:8081','222.74.202.229:80','222.74.202.244:80','106.58.191.218:8888','222.74.202.229:8080']

然后可以拿来模拟爬百度:

import requests
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36'
}for ip in http_ip_pool:try:r = requests.get(f"http://www.baidu.com/",headers=headers, proxies={'http': ip}, timeout=1)print(r.status_code)except Exception as e:print(e)
HTTPConnectionPool(host='139.9.25.69', port=3128): Max retries exceeded with url: http://www.baidu.com/ (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000028D6A993248>, 'Connection to 139.9.25.69 timed out. (connect timeout=1)'))
200
200
HTTPConnectionPool(host='106.58.191.24', port=8888): Max retries exceeded with url: http://www.baidu.com/ (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000028D6B59C2C8>, 'Connection to 106.58.191.24 timed out. (connect timeout=1)'))
200
HTTPConnectionPool(host='47.111.71.29', port=8081): Max retries exceeded with url: http://www.baidu.com/ (Caused by ProxyError('Cannot connect to proxy.', RemoteDisconnected('Remote end closed connection without response')))
200
200
HTTPConnectionPool(host='106.58.191.218', port=8888): Max retries exceeded with url: http://www.baidu.com/ (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000028D6A9C2F88>, 'Connection to 106.58.191.218 timed out. (connect timeout=1)'))
200

可以看到只有一半的代理IP能在指定时间内成功访问百度,说明免费的代理IP就是不如收费的稳定。

定期爬取并清除失效的代理IP

只要再完成这部分,我们的代理IP池就能够初见雏形,冲!

最终完成代码:

import requests
import pandas as pd
import redis
from threading import Timer
import timeheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36'
}def proxie_ip_validity_check(proxie_ip, proxie_type='http', timeout=2):try:r = requests.get(f"{proxie_type}://httpbin.org/ip",proxies={proxie_type: proxie_ip}, timeout=timeout)if r.status_code == 200:return Truereturn Falseexcept:return Falseredis_conn = redis.Redis(host='192.168.3.31', port=6379)def crawl_proxy_ip2redis():for page in range(1, 20):print("当前爬取页面:", page)url = f'https://www.kuaidaili.com/free/intr/{page}'r = requests.get(url, headers=headers)r.encoding = 'u8'ip_df, = pd.read_html(r.text)for ip, port, proxie_type in ip_df[["IP", "PORT", "类型"]].values:proxie_ip = f"{ip}:{port}"proxie_type = proxie_type.lower()if proxie_ip_validity_check(proxie_ip, proxie_type, 2):redis_conn.sadd(f"proxie_ip_{proxie_type}", proxie_ip)def get_proxy_ip_pool(proxie_type='http'):http_ip_bytes = redis_conn.smembers(f"proxie_ip_{proxie_type}")http_ip_pool = list(map(bytes.decode, http_ip_bytes))return http_ip_pooldef clear_invalid_proxie_ip():print("开始清空失效代理ip:")for proxie_type in ['http', 'https']:for ip in get_proxy_ip_pool(proxie_type):if not proxie_ip_validity_check(ip, proxie_type, 2):print(proxie_type, ip, "失效")redis_conn.srem(f"proxie_ip_{proxie_type}", ip)crawl_proxy_ip2redis()
while True:# 5分钟后清空一次失效的代理ipTimer(5 * 60, clear_invalid_proxie_ip, ()).start()# 10分钟后下载一次代理ipTimer(10 * 60, crawl_proxy_ip2redis, ()).start()# 每隔10分钟一个周期time.sleep(10 * 60)

目前测试,这个Redis代理IP池还算好使,作为一个雏形勉强能用。

可以通过Redis图形化工具查看代理IP池的存储情况:

我使用的工具叫Redis Desktop Manager,可以百度下载。

目前我个人还算满意。

Pandas一键爬取解析代理IP与代理IP池的维护相关推荐

  1. (一)基础:通过简单HTTP请求和正则进行数据爬取解析

    (一)基础:通过简单HTTP请求和正则进行数据爬取解析 文章目录 (一)基础:通过简单HTTP请求和正则进行数据爬取解析 发送简单http请求 如何使用代理ip发送请求 常用的User-Agent 发 ...

  2. Java爬取解析去哪儿景点信息

    前言:这两周在做 Web 课的大作业,顺便琢磨了一下如何使用 Java 从网上获取一些数据,现在写这篇博客记录一下. PS:这里仅限交流学习用,如利用代码进行恶意攻击他网站,和作者无关!!! Java ...

  3. python一键爬取视频_超详细Python-一键爬取图片、音频、视频资源

    使用Python爬取任意网页的资源文件,比如图片.音频.视频:一般常用的做法就是把网页的HTML请求下来通过XPath或者正则来获取自己想要的资源,这里我做了一个爬虫工具软件,可以一键爬取资源 媒体文 ...

  4. 爬取西刺网的免费IP

    在写爬虫时,经常需要切换IP,所以很有必要自已在数据维护库中维护一个IP池,这样,就可以在需用的时候随机切换IP,我的方法是爬取西刺网的免费IP,存入数据库中,然后在scrapy 工程中加入tools ...

  5. 商品评论html,京东商品评论太多(带你一键爬取京东商品评论)

    京东商品评论太多(带你一键爬取京东商品评论) 一.项目说明 1.项目背景 一天,一朋友扔给我一个链接https://item.jd.com/100000499657.html,让我看看这个歌商品的所有 ...

  6. 根据url一键爬取前端页面资源文件,恐怖如斯-----小飞兔

    前言 有一天你在网上发现一个很好看的前端页面,你想要弄下来在自己的项目上使用,于是你去查看源码,复制html代码和资源文件,过程非常的麻烦,而且很可能缺胳膊少腿,这里我给大家推荐一款可以一键爬取前端页 ...

  7. 还在苦于Kindle的epub格式吗?python爬虫,一键爬取小说加txt转换epub。

    还在苦于Kindle的epub格式吗?python爬虫,一键爬取小说加txt转换epub. 项目地址: https://github.com/Fruiticecake/dubuNovel/blob/m ...

  8. 代理IP爬取和验证(快代理西刺代理)

    前言 仅仅伪装网页agent是不够的,你还需要一点新东西 今天主要讲解两个比较知名的国内免费IP代理网站:西刺代理&快代理,我们主要的目标是爬取其免费的高匿代理,这些IP有两大特点:免费,不稳 ...

  9. pandas爬虫爬取网页表格

    简介 一般的爬虫套路无非是发送请求.获取响应.解析网页.提取数据.保存数据等步骤.构造请求主要用到requests库,定位提取数据用的比较多的有xpath和正则匹配.一个完整的爬虫,代码量少则几十行, ...

  10. 爬虫(三):爬取西刺高匿代理

    抓取西刺高匿代理,并验证IP的可用性,存储到本地文件中. 代码如下 # 导入模块 import requests import chardet import random from scrapy.se ...

最新文章

  1. 《树莓派Python编程指南》——2.3 小结
  2. 馅饼还是陷阱,TMG2010升级经验谈
  3. Python学习笔记(七)函数的使用
  4. 没有可用于当前位置的源代码
  5. 大家所推崇的Redis分布式锁真的就万无一失吗?
  6. 水晶报表-横向设计页面,设置网格高度
  7. python __call__一般用在哪些地方_Python __call__内置函数的作用和用法
  8. 获取硬盘总容量,柱面数,磁道数,扇区数
  9. svn 把本地的项目,上传到服务器端
  10. 3h精通OpenCV(六)-图像堆叠
  11. 在浏览器上运行Qt应用 emscripten-qt
  12. 计算机c语言报告册,计算机c语言实验报告.docx
  13. linux pxe dhcp 讲解,RHEL 5 PXE+DHCP+NFS+SFTP无人职守网络安装配置
  14. linux 3t 硬盘无法识别,希捷(3T)硬盘故障处理备忘
  15. Java连接redis集群报错,connection refused 和Could not get a resource from the pool
  16. MySQL全文索引:中文语义分词检索
  17. codewars练习(javascript)-2021/1/19
  18. 使用cropper插件实现图片的裁剪和预览
  19. 机器学习的几种分类损失函数
  20. Ubuntu下U盘变成只读解决方法

热门文章

  1. 免费音效素材,拿走不谢。
  2. 安卓 多条通知_【安卓+苹果】石头阅读,全网小说、漫画免费看,最好用的追书神器!...
  3. 小米浏览器禁止java,如何禁止小米手机浏览器中弹出窗口广告
  4. 迅雷精简版绿色优化版
  5. Eucalyptus常用命令示例
  6. 希尔伯特空间、欧几里德空间
  7. springboot集成梦网云科技api发送短信
  8. 描述TCP和UDP区别
  9. easydarwin ffmpeg
  10. php的curl选项curlopt,CURLOPT_NOBODY选项,php中文手册中坑爹的翻译!