首页 > 其他分享 > 如何实现通用爬虫并检测可用性?

如何实现通用爬虫并检测可用性?

时间:2023-02-14 19:01:50浏览次数:53  
标签:HTTP 检测 self 可用性 爬虫 spider proxy run pool

一、实现运行爬虫模块

我们的目标:根据配置文件信息, 加载爬虫,抓取HTTP代理,进行校验,如果可用,写入到数据库中

根据以下思路:

1.在run_spider.py中,创建RunSpider类

2.提供一个运行爬虫的run方法,作为运行爬虫的入口,实现核心的处理逻辑

  • 根据配置信息,获取爬虫对象列表
  • 遍历爬虫对象列表,获取爬虫对象,遍历爬虫对象的get_proxies方法,获取HTTP代理
  • 检测HTTP代理(HTTP代理检测模块)
  • 如果可用,写入数据库(数据库模块)
  • 处理异常,防止一个爬虫内部出错了,影响其他的爬虫

3.使用异步来执行每一个爬虫任务,以提高抓取HTTP代理效率

  • 在init方法中创建协程池对象
  • 把处理一个代理爬虫的代码抽到一个方法
  • 使用异步执行这个方法
  • 调用协程的join方法,让当前线程等待队列任务的完成

4.使用schedule模块,实现每隔一定的时间,执行一次爬取任务

  • 定义一个start的类方法
  • 创建当前类的对象,调用run方法
  • 使用schedule模块,每隔一定的时间,执行当前对象的run方法

所以我们可以在run_spider.py中,创建RunSpider类,进而修改settings.py增加HTTP代理爬虫的配置信息。具体代码如下:

from gevent import monkey

monkey.patch_all()
import importlib
from gevent.pool import Pool
from proxy_pool.settings import SPIDER_LIST, RUN_SPIDER_INTERVAL
from proxy_pool.utils.http_validate import check_proxy
from proxy_pool.utils.mongo_pool import MongoPool
from proxy_pool.utils.log import logger
import schedule
import time


class RunSpider(object):
def __init__(self):
self.mongo_pool = MongoPool()
self.coroutine_pool = Pool()

def get_spider_from_settings(self):
for class_full_name in SPIDER_LIST:
module_name, class_name = class_full_name.rsplit('.', 1)
module = importlib.import_module(module_name)
spider_class = getattr(module, class_name)
spider = spider_class()
yield spider

def process_one_spider(self, spider):
try:
for proxy in spider.run():
check_proxy(proxy)
if proxy.speed != -1:
self.mongo_pool.insert_one(proxy)
except Exception as ex:
logger.warning(ex)

def run(self):
spider_list = self.get_spider_from_settings()
for spider in spider_list:
self.coroutine_pool.apply_async(func=self.process_one_spider, args=(spider,))
self.coroutine_pool.join()

@classmethod
def start(cls):
rs = cls()
rs.run()
schedule.every(RUN_SPIDER_INTERVAL).hours.do(rs.run)
while True:
schedule.run_pending()
time.sleep(1)


if __name__ == "__main__":
RunSpider().run()

settings.py代码如下:

# 配置run_spider模块
# ---配置spider
SPIDER_LIST = {
"proxy_pool.core.proxy_spider.xila_spider.XiLaSpider",
"proxy_pool.core.proxy_spider.ip3366_spider.Ip3366Spider",
}
# ---配置schedule的周期
RUN_SPIDER_INTERVAL = 4

二、实现HTTP代理检测模块

之后,我们需要检查HTTP代理可用性,保证代理池中HTTP代理基本可用。这部分基本是大家耳熟能详的:

1.在proxy_test.py中,创建ProxyTester类

2.提供一个run方法,用于处理检测HTTP代理核心逻辑

我们可以先从数据哭中获取所有的HTTP代理,然后从HTTP代理列表中,检查HTTP代理的可用性,如果HTTP代理不可用,让代理分数-1,如果代理分数=0,就从数据库中删除该代理,否则更新该代理,如果代理可用,就恢复该代理的分数,更新到数据库中。

3.为了提高检查的速度,使用异步来执行检测任务

首先,我们需要把要检测的HTTP代理,放到队列中;

其次,把检查一个代理可用性的代码,抽取到一个方法中,从队列中获取HTTP代理,进行检查,检查完毕,调度队列的task_done方法;

然后通过异步回调,使用死循环不断执行这个方法;

最后,开启多个一个异步任务,来处理HTTP代理的检测,可以通过配置文件指定异步数量。

4.使用schedule模块,每隔一定的时间,执行一次检测任务

具体代码如下

from gevent import monkey
monkey.patch_all()

from gevent.pool import Pool
from queue import Queue
from proxy_pool.utils.mongo_pool import MongoPool
from proxy_pool.settings import ASYNC_COUNT, DEFAULT_SCORE, TEST_SPIDER_INTERVAL
from proxy_pool.utils.http_validate import check_proxy
import schedule
import time


class ProxyTest(object):
def __init__(self):
self.mongo_pool = MongoPool()
self.proxy_queue = Queue()
self.coroutine_pool = Pool()

def check_one_proxy(self):
proxy = self.proxy_queue.get()
check_proxy(proxy)
if proxy.speed == -1:
proxy.score -= 1
if proxy.score == 0:
self.mongo_pool.delete_one(proxy)
self.mongo_pool.update_one(proxy)
proxy.score = DEFAULT_SCORE
self.mongo_pool.update_one(proxy)
self.proxy_queue.task_done()

def check_call_back(self, temp):
self.coroutine_pool.apply_async(func=self.check_one_proxy, callback=self.check_call_back)

def run(self):
for proxy in self.mongo_pool.find_all():
self.proxy_queue.put(proxy)
for i in range(ASYNC_COUNT):
self.coroutine_pool.apply_async(func=self.check_one_proxy, callback=self.check_call_back)
self.coroutine_pool.join()
self.proxy_queue.join()

@classmethod
def start(cls):
rs = cls()
rs.run()
schedule.every(TEST_SPIDER_INTERVAL).hours.do(rs.run)
while True:
schedule.run_pending()
time.sleep(1)

if __name__ == "__main__":
obj = ProxyTest()
obj.start()

本文转载自​​https://zhuanlan.zhihu.com/p/156778725​

标签:HTTP,检测,self,可用性,爬虫,spider,proxy,run,pool
From: https://blog.51cto.com/u_15908682/6057388

相关文章

  • AI人脸检测EasyCVR视频融合平台接口返回数据不全是什么原因?
    EasyCVR平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。平台可支持多协议、多类型......
  • C#网络爬虫开发
    1前言爬虫一般都是用Python来写,生态丰富,动态语言开发速度快,调试也很方便但是我要说但是,动态语言也有其局限性,笔者作为老爬虫带师,几乎各种语言都搞过,现在这个任务并不复......
  • 【opencv c++】实现yolov5部署onnx模型完成目标检测
    总代码#include<fstream>#include<sstream>#include<iostream>#include<opencv2/dnn.hpp>#include<opencv2/imgproc.hpp>#include<opencv2/highgui.hpp>usin......
  • Python爬虫:从js逆向了解西瓜视频的下载链接的生成
    文章内容在csdn上,链接为:Python爬虫:从js逆向了解西瓜视频的下载链接的生成参考代码为:importrequestsfromcrawlers.userAgentimportuseragentfromlxmlimportetre......
  • python爬虫学习——列表
    namelist=[]#定义一个空的列表namelist1=["小张","小红","小李"]print(namelist1[0])print(namelist1[1])print(namelist1[2])testlist=[1,"测试"]#列表中......
  • 位图:爬虫URL去重最佳方案
    网页爬虫,解析已爬取页面中的网页链接,再爬取这些链接对应网页。而同一网页链接有可能被包含在多个页面中,这就会导致爬虫在爬取的过程中,重复爬取相同的网页。1如何避免重复爬......
  • 纽扣电池上架亚马逊UL4200A检测项目流程
    纽扣电池(buttoncell)也称扣式电池,是指外形尺寸象一颗小纽扣的电池,一般来说直径较大,厚度较薄。纽扣电池因体形较小,故在各种微型电子产品中得到了广泛的应用,直径从4.8mm至30m......
  • 提高IT运维效率,深度解读京东云AIOps落地实践(异常检测篇(二))
    作者:张宪波、张静、李东江如何提高IT运维效率是众多运维人员的难题,这不仅是对内容繁杂、持续变化、支持不同的业务需求加以描述、加载和维护,更要对运维和业务运维需求、过程......
  • 提高IT运维效率,深度解读京东云AIOps落地实践(异常检测篇(二))
    作者:张宪波、张静、李东江如何提高IT运维效率是众多运维人员的难题,这不仅是对内容繁杂、持续变化、支持不同的业务需求加以描述、加载和维护,更要对运维和业务运维需求、过程......
  • Pytorch_人脸检测
    人脸检测人脸识别的目的就是要对图片和视频中人脸的身份进行判断FaceRecognitiondockerpullanimcogn/face_recognition:cpu-nightlyHarr级联人脸检测、Dlib人脸检......