python构建IP代理池(Proxy Pool)[通俗易懂]
2023-06-13 09:11:40 时间
大家好,又见面了,我是你们的朋友全栈君。
基本原理
代理实际上指的就是代理服务器,它的功能是代理网络用户去取得网络信息 。也可以说它是网络信息的中转站 。
在我们正常请求一个网站时, 是将请求发送给 Web 服务器,Web 服务器把响应传回给我们 。 如果设置了代理服务器 , 实际上就是在本机和服务器之间搭建了一个桥, 此时本机不是直接 向 Web 服务器发起请求,而是向代理服务器发出请求,请求会发送给代理服务器,然后由代理服务器再发送给 Web 服务器,接着由代理服务器再把 Web 服务器返回的响应转发给本机。 这样我们同样可以正常访问网页,但这个过程中 Web 服务器识别出的真实 IP 就不再是我们本机的 IP 了,就成功实现了 IP 伪装,解决爬虫中封IP的难题。
了解代理服务器的基本原理后,我们不禁会想到几个问题,代理IP从何而来?如何保证代理可用性?代理如何存储?如何使用这些代理?
- 获取代理IP: 爬取网站的免费代理。比如西刺、快代理之类有免费代理的网站, 但是这些免费代理大多数情况下都是不好用的,所以比较靠谱的方法是购买付费代理。当然,如果你有更好的代理接口也可以自己接入。
- 检测IP代理可用性: 因为免费代理大部分是不可用的,所以采集回来的代理IP不能直接使用,可以写检测程序不断的去用这些代理访问一个稳定的网站,看是否可以正常使用。
- 存储代理IP: 存储的代理IP首先要保证代理不重复 , 要检测代理的可用情况,还要动态实时处理每个代理,本文利用来MongoDB存储,当然也可用其他方式存储。
- 使用代理:最简单的办法就是用 API 来提供对外服务的接口 。
IP代理池设计
我们了解了代理池的四大问题,所以我们可以根据这四个问题去分析设计一个代理池框架,我们可以分成四个模块。分别是获取模块、检测模块、存储模块、接口模块 。这样不仅有利于我们的维护,也使得可以更高效的完成我们的需求。
- 架构图
代码模块
在这里只是简单的写出了代码模块的实现,并不完整不具有逻辑性,如想查看获取源代码,请移步到GitHub:https://github.com/wanhaiwei/proxypool
- 获取模块
import requests
import chardet
import traceback
from lxml import etree
class Downloader(object):
def __init__(self):
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
def download(self, url):
print('正在下载页面:{}'.format(url))
try:
resp = requests.get(url, headers=self.headers)
resp.encoding = chardet.detect(resp.content)['encoding']
if resp.status_code == 200:
return self.xpath_parse(resp.text)
else:
raise ConnectionError
except Exception:
print('下载页面出错:{}'.format(url))
traceback.print_exc()
def xpath_parse(self, resp):
try:
page = etree.HTML(resp)
trs = page.xpath('//div[@id="list"]/table/tbody/tr')
proxy_list = []
for tr in trs:
ip = tr.xpath('./td[1]/text()')[0]
port = tr.xpath('./td[2]/text()')[0]
proxy = {
'proxy': ip + ':' + port
}
proxy_list.append(proxy)
return proxy_list
except Exception:
print('解析IP地址出错')
traceback.print_exc()
if __name__ == '__main__':
print(Downloader().download('https://www.kuaidaili.com/free/inha/1/'))
- 存储模块
import pymongo
from pymongo.errors import DuplicateKeyError
class MongoDB(object):
def __init__(self):
self.client = pymongo.MongoClient()
self.db = self.client['proxypool3']
self.proxies = self.db['proxies']
self.proxies.ensure_index('proxy', unique=True)
self.proxies.create_index()
# createIndex()
def insert(self, proxy):
try:
self.proxies.insert(proxy)
print('插入成功:{}'.format(proxy))
except DuplicateKeyError:
pass
def delete(self, conditions):
self.proxies.remove(conditions)
print('删除成功:{}'.format(conditions))
def update(self, conditions, values):
self.proxies.update(conditions, {"$set": values})
print('更新成功:{},{}'.format(conditions,values))
def get(self, count, conditions=None):
conditions = conditions if conditions else {}
count = int(count)
items = self.proxies.find(conditions, limit=count).sort('delay', pymongo.ASCENDING)
items = list(items)
return items
def get_count(self):
return self.proxies.count({})
if __name__ == '__main__':
m = MongoDB()
print(m.get(3))
- 检测模块
import requests
import time
import traceback
from requests.exceptions import ProxyError, ConnectionError
from db.mongo_db import MongoDB
from multiprocessing.pool import ThreadPool
def valid_many(proxy_list, method):
pool = ThreadPool(16)
for proxy in proxy_list:
pool.apply_async(valid_one, args=(proxy, method))
pool.close()
pool.join()
def valid_one(proxy, method, url='https://www.baidu.com'):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
}
proxies = {
'http': 'http://' + proxy['proxy'],
'https': 'http://' + proxy['proxy']
}
try:
start_time = time.time()
# requests.packages.urllib3.disable_warnings()
resp = requests.get(url, headers=headers, proxies=proxies, timeout=5, verify=False)
delay = round(time.time() - start_time, 2)
if resp.status_code == 200:
proxy['delay'] = delay
if method == 'insert':
MongoDB().insert(proxy)
elif method == 'check':
MongoDB().update({'proxy': proxy['proxy']}, {'delay': proxy['delay']})
else:
if method == 'check':
MongoDB().delete({'proxy': proxy['proxy']})
except (ProxyError, ConnectionError):
if method == 'check':
MongoDB().delete({'proxy': proxy['proxy']})
except Exception:
traceback.print_exc()
- API接口模块
import flask
import json
from db.mongo_db import MongoDB
app = flask.Flask(__name__)
@app.route('/one')
def get_one():
proxies = MongoDB().get(1)
result = [proxy['proxy'] for proxy in proxies]
return json.dumps(result)
@app.route('/many')
def get_many():
args = flask.request.args
proxies = MongoDB().get(args['count'])
result = [proxy['proxy'] for proxy in proxies]
return json.dumps(result)
def run():
app.run()
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/144823.html原文链接:https://javaforall.cn
相关文章
- Python进阶33-Django cookie和session
- Python面试基础知识_python自学需要哪些基础知识
- Python从入门到进阶之六:Pycharm中如何加入代理
- python语言变量命名规则有什么_Python变量命名规则(超级详细)
- Python爬虫实战——搭建自己的IP代理池[通俗易懂]
- python 之免费ip代理池[通俗易懂]
- Python入门系列(十一)一篇搞定python操作MySQL数据库
- Python搭建代理IP池(一)- 获取 IP[通俗易懂]
- python监控网站更新_Python 通过网站search功能监控网站内容更新[通俗易懂]
- Python深耕之图像深度学习必备工具包
- python selenium 实现自动化输入账号 word 邮箱
- Python udp编程_python socket udp
- 下列python语句的输出结果是print_下列 Python语句的输出结果是「建议收藏」
- Python获取免费代理IP,并全部测试一遍,结果大失所望
- python用ARIMA模型预测CO2浓度时间序列实现|附代码数据
- Python爬虫如何设置静态IP代理定时自动更换IP代理?
- python-Python与SQLite数据库-SQLite数据库的基本知识(一)
- 小白的Python之路 day5 python模块详解及import本质编程语言
- Linux下如何快速卸载Python环境(linux如何卸载python)
- Eclipse+PyDec运行Python程序
- Python迭代器与可迭代对象的区别与联系
- python、java爬虫使用代理的区别
- Python在MSSQL中的应用实践(python与mssql)
- 用代理IP轻松存储在Redis中(代理ip存Redis)