异步爬虫---

代码结构分析

这是一个同步新闻爬虫程序,主要包含以下几个部分:

们把爬虫设计为一个类,类在初始化时,连接数据库,初始化logger,创建网址池,加载hubs并设置到网址池。

爬虫开始运行的入口就是run(),它是一个while循环,设计为永不停息的爬。先从网址池获取一定数量的url,然后对每个url进行处理,

处理url也就是实施抓取任务的是process(),它先通过downloader下载网页,然后在网址池中设置该url的状态。接着,从下载得到的html提取网址,并对得到的网址进行过滤(filter_good()),过滤的原则是,它们的host必须是hubs的host。最后把下载得到的html存储到数据。

运行这个新闻爬虫很简单,生成一个NewsCrawlerSync的对象,然后调用run()即可。当然,在运行之前,要先在config.py里面配置MySQL的用户名和密码,也要在crawler_hub表里面添加几个hub网址才行。

##思考题: 如何收集大量hub列表

比如,我想要抓新浪新闻 news.sina.com.cn , 其首页是一个hub页面,但是,如何通过它获得新浪新闻更多的hub页面呢?小猿们不妨思考一下这个问题,并用代码来实现一下。

这个时候已经抓取到很多网页了,但是怎么抽取网页里的文字呢?

1. 异步的downloader

还记得我们之前使用requests实现的那个downloader吗?同步情况下,它很好用,但不适合异步,所以我们要先改造它。幸运的是,已经有aiohttp模块来支持异步http请求了,那么我们就用aiohttp来实现异步downloader。

async def fetch(session, url, headers=None, timeout=9):_headers = {'User-Agent': ('Mozilla/5.0 (compatible; MSIE 9.0; ''Windows NT 6.1; Win64; x64; Trident/5.0)'),}if headers:_headers = headerstry:async with session.get(url, headers=_headers, timeout=timeout) as response:status = response.statushtml = await response.read()encoding = response.get_encoding()if encoding == 'gb2312':encoding = 'gbk'html = html.decode(encoding, errors='ignore')redirected_url = str(response.url)except Exception as e:msg = 'Failed download: {} | exception: {}, {}'.format(url, str(type(e)), str(e))print(msg)html = ''status = 0redirected_url = urlreturn status, html, redirected_url

这个异步的downloader,我们称之为fetch(),它有两个必须参数:

  • seesion: 这是一个aiohttp.ClientSession的对象,这个对象的初始化在crawler里面完成,每次调用fetch()时,作为参数传递。
  • url:这是需要下载的网址。

实现中使用了异步上下文管理器(async with),编码的判断我们还是用cchardet来实现。
有了异步下载器,我们的异步爬虫就可以写起来啦~

  1. 导入部分:引入必要的库和模块
  2. 主类定义:NewsCrawlerSync 类,包含爬虫的主要功能
  3. 初始化方法:__init__ 方法,初始化数据库连接、日志和 URL 池
  4. 辅助方法:如加载枢纽 URL、保存数据到数据库、过滤 URL 等
  5. 核心处理方法:process 方法处理 URL 下载和内容提取
  6. 运行方法:run 方法实现爬虫的主循环

涉及的知识点

  1. 网络爬虫基础:URL 处理、HTML 下载和解析
  2. 数据库操作:使用 MySQL 存储爬取的 URL 和 HTML 内容
  3. 数据压缩:使用 LZMA 算法压缩 HTML 内容
  4. 哈希算法:使用 farmhash 生成 URL 的哈希值
  5. 日志记录:使用自定义日志函数记录操作
  6. URL 管理:使用自定义的 UrlPool 类管理 URL 队列
  7. 网页解析:使用正则表达式提取链接

执行流程

  1. 初始化爬虫对象,建立数据库连接,初始化日志和 URL 池
  2. 从数据库加载枢纽 URL,并将它们添加到 URL 池
  3. 进入主循环,每次从 URL 池取出 5 个 URL
  4. 对每个 URL,下载其内容并处理
  5. 如果是枢纽页面,提取其中的链接并过滤,将有效链接添加到 URL 池
  6. 如果是普通新闻页面,将其内容保存到数据库
  7. 重复步骤 3-6,直到程序停止

现在我将按照这个思路来详细分析代码的结构、知识点和流程。

新闻爬虫代码分析

一、整体结构

这是一个同步新闻爬虫程序,采用面向对象设计,核心类为 NewsCrawlerSync,主要包含以下模块:

  1. 数据存储模块:通过 ezpymysql.Connection 连接 MySQL 数据库,存储 URL 和 HTML 内容
  2. URL 管理模块:使用 UrlPool 类管理待爬取 URL 队列
  3. 下载处理模块:通过 fn.downloader 下载网页内容
  4. 链接提取模块:通过 fn.extract_links_re 从 HTML 中提取链接
  5. 日志记录模块:使用 fn.init_file_logger 记录操作日志
二、核心知识点
1. 数据库操作
  • 数据去重:通过farmhash.hash64(url)生成 URL 哈希值,避免重复存储相同内容
  • SQL 执行:使用参数化查询防止 SQL 注入(如db.execute(sql, urlhash, url, html_lzma)
  • 异常处理:捕获 1062 错误(唯一键冲突),处理数据重复情况
2. 网页处理
  • URL 解析:使用urllib.parse.urlparse解析 URL 的 host 部分
  • 内容压缩:通过lzma.compress压缩 HTML 内容,减少存储体积
  • 链接提取:通过正则表达式从 HTML 中提取链接(fn.extract_links_re
3. 爬虫架构
  • 枢纽页面机制:从crawler_hub表加载枢纽 URL,作为爬虫入口
  • URL 过滤:只爬取枢纽页面关联的域名(self.hub_hosts集合)
  • 状态管理:通过UrlPool.set_status记录 URL 爬取状态
三、执行流程详解
1. 初始化阶段

图片

代码

创建NewsCrawlerSync实例

初始化数据库连接

初始化日志记录器

初始化UrlPool

调用load_hubs加载枢纽URL

创建NewsCrawlerSync实例

初始化数据库连接

初始化日志记录器

初始化UrlPool

调用load_hubs加载枢纽URL

豆包

你的 AI 助手,助力每日工作学习

  • crawler_hub表读取枢纽 URL,提取域名存入hub_hosts集合
  • 将枢纽 URL 添加到 UrlPool,设置 300 秒的重复爬取间隔
2. 主爬取循环

图片

代码

开始run循环

从UrlPool取出5个URL

是否有URL?

遍历每个URL

调用process处理URL

开始run循环

从UrlPool取出5个URL

是否有URL?

遍历每个URL

调用process处理URL

豆包

你的 AI 助手,助力每日工作学习

3. 单 URL 处理流程

图片

代码

process方法

下载URL内容

记录URL状态

是否为枢纽页面?

提取页面所有链接

过滤出枢纽域名的链接

将有效链接添加到UrlPool

保存HTML到数据库

process方法

下载URL内容

记录URL状态

是否为枢纽页面?

提取页面所有链接

过滤出枢纽域名的链接

将有效链接添加到UrlPool

保存HTML到数据库

豆包

你的 AI 助手,助力每日工作学习

四、关键方法解析
1. save_to_db - 数据存储核心

python

运行

def save_to_db(self, url, html):# 生成URL哈希值urlhash = farmhash.hash64(url)# 检查是否已存在相同哈希的记录d = self.db.get('select url from crawler_html where urlhash=%s', urlhash)if d:# 处理哈希冲突if d['url'] != url:self.logger.error('farmhash collision')return True# 压缩HTML内容if isinstance(html, str):html = html.encode('utf8')html_lzma = lzma.compress(html)# 插入数据库,处理唯一键冲突try:self.db.execute('insert into crawler_html(urlhash, url, html_lzma) values(%s, %s, %s)',urlhash, url, html_lzma)return Trueexcept Exception as e:if e.args[0] == 1062:  # 重复记录return Trueelse:traceback.print_exc()raise e
2. process - 爬虫核心逻辑

python

运行

def process(self, url, ishub):# 下载网页内容status, html, redirected_url = fn.downloader(url)# 更新URL状态self.urlpool.set_status(url, status)if redirected_url != url:self.urlpool.set_status(redirected_url, status)# 处理非200状态码if status != 200:return# 处理枢纽页面if ishub:newlinks = fn.extract_links_re(redirected_url, html)  # 提取所有链接goodlinks = self.filter_good(newlinks)  # 过滤枢纽域名链接self.urlpool.addmany(goodlinks)  # 添加到URL池# 处理新闻页面else:self.save_to_db(redirected_url, html)  # 保存到数据库
五、技术特点与注意事项
  1. 同步爬虫特性

    • 单线程执行,通过循环依次处理 URL
    • 适合小规模爬取,大规模爬取需改造为异步模式
  2. 去重机制

    • 基于 farmhash 哈希值去重,可能存在哈希冲突(代码中已处理)
    • 数据库中通过urlhash建立唯一索引强化去重
  3. 可优化点

    • 改为异步爬虫(使用asyncio)提升并发效率
    • 添加 User-Agent 轮换和请求延迟,避免被封 IP
    • 完善代理 IP 池机制,应对反爬措施

通过这个爬虫框架,可以实现对指定新闻网站的持续爬取,并将内容结构化存储到数据库中,适合作为入门级爬虫系统的参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/89058.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

04 dnsmasq 的环境搭建

前言 这里介绍一下 dnsmasq 的调试环境的搭建 这是一种比较常见的开远的 dns 服务器 git 仓库在 git://thekelleys.org.uk/dnsmasq.git dnsmasq 的编译 首先是 clone 代码, git clone git://thekelleys.org.uk/dnsmasq.git 然后是开始编译 dnsmasq 最顶层的目录结构如下…

visual studio2019+vcpkg管理第三方库

下载 vcpkg官方教程 git clone https://github.com/microsoft/vcpkg.git cd vcpkg && bootstrap-vcpkg.bat注意:git clone一直失败,我直接在github仓库下载的zip,一样可以 设置环境变量 E:\software\vcpkg 安装你想要的库 比如…

logger2js - JavaScript日志与调试工具库

logger2js - JavaScript日志与调试工具库 logger2js是一个功能强大的前端JavaScript日志与调试工具库,提供了丰富的日志输出、性能测试和代码调试功能。该库支持配置化引入,包含5种皮肤风格和丰富的API接口,如 a l e r t 增强方法、 alert增…

影像组学5:Radiomics Score的计算

Rad-score(全称 Radiomics score,影像组学评分)是通过数学模型将影像组学提取的多个特征整合为一个综合性指标,从而简化临床分析与决策。 前文已介绍影像组学的病灶分割、特征提取及筛选流程,本节将重点阐述 Rad-scor…

性能测试——搭建Prometheus+Grafana平台(超详细版)

一、搭建influxdb prometheus grafana Jmeter监控平台 1、目的:对性能测试的结果进行持久化存储。 2、每个组件介绍 Jmeter:性能测试工具,可以收集到服务器的性能测试指标:统计TPS、响应时间、线程数、错误率等信息。influxd…

微服务--nacos+feign

微服务使用到了我们的多模块开发,父级工程可以在modules管理子模块 子模块中也会定义父模块 1. Nacos注册中心 Nacos已成为Java微服务生态的事实标准组件,在2023年中国Java开发者调研中占比达62%。其优势在于将服务发现与配置管理统一,显著降…

基于Python的二手房源信息爬取与分析的设计和实现,7000字论文编写

摘要 本文设计并实现了一个基于 Python 的二手房源信息爬取与分析系统。该系统通过网络爬虫技术自动从房地产网站获取二手房源信息,经过数据清洗、存储后进行多维度分析,并通过可视化界面展示分析结果。系统采用模块化设计,包括爬虫模块、数…

力扣HOT100之栈:739. 每日温度

这道题是单调栈的一个经典应用,这里我们使用单调递减的栈(从栈底到栈顶单调递减)来实现,首先我们创建一个与temperatures大小一致的全0数组result,然后我们通过一个for循环,通过下标访问的方式遍历所有元素…

vue3 报错Missing semicolon

快速定位问题: 一、在git中对比改动,实在不行重置。 二、找分号或逗号 三、误碰键盘,多了空格or一些字母,删除即可。如下

在pyCharm中创建新的conda环境

在conda中创建pychars环境 打开 CMD 或 PowerShell 或 Anaconda Prompt 输入以下命令: conda create -n pychars python3.10你可以把 3.10 换成你需要的 Python 版本,如 3.9、3.11 等。 创建完成后激活环境: conda activate pychars在 Py…

如何确定某个路由器的路由表?(计算机网络)

以下题为例 题目说要路由表关键是目的网络地址和下一跳地址 那么我们第一步先确定目的网络地址。 一共有四个网络,即有四个目的网络地址:15.0.0.0 20.0.0.0 30.0.0.0 40.0.0.0 下一跳地址就是去往目地网络的下一个ip地址 。 我们这里是要的…

ubuntu 系统 多条命令通过 bash 脚本执行

ubuntu 系统 多条命令通过 bash 脚本执行。 1、新建sh脚本。 vim run.sh 2、示例命令,写入run.sh文件内,具体命令如下: #!/bin/bash# 切换到指定目录 cd /work_space/build/bin# 执行程序 ./demo 3、给sh脚本权限。 chmod x run.sh 4、执行sh脚本…

《拆解问题的技术》笔记

思维导图 拆解问题的技术 拆解职场难题 拆解项目难题 拆解简报企划难题 拆解学习难题 拆解人生难题

langChain构建ChatRobot(1)—基础对话

摘要:本文介绍利用langChain核心组件Models里的Chat Models构建基本的Chatbot,能实现简单的问答。 文章目录 概述Chat Model1. message对象1.1 消息类型介绍:1.2 使用场景: 2. 利用ChatModel构建简单的 Chatbot2.1 实现基本的问答…

行为模式-迭代器模式

定义: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该 对象的内部细节。) 迭代器模式通…

图像处理算法的学习笔记

一、常见噪声简介 1. 高斯噪声 最普遍,最难用肉眼精确判断。图像整体看起来"颗粒感"很强,像蒙了一层半透明的"薄纱"或"雪花点"(就像老式电视的雪花屏),覆盖整个画面。噪声点是细小的、…

《Java开发工具全解析:从基础到前沿》

一、引言 在当今数字化时代,软件开发犹如一座庞大而复杂的大厦,支撑着我们生活中方方面面的应用。而 Java,作为软件开发领域中极为重要的一门编程语言,宛如大厦的基石,发挥着不可替代的关键作用。 自 1995 年正式诞生…

[11-4]SPI通信外设 江协科技学习笔记(5个知识点)

1 2 3 TDR、TXE、RDR、RXNE 这些术语通常与串行通信接口有关,特别是在使用 UART(通用异步收发传输器)或 USART(通用同步/异步收发传输器)时。下面是每个术语的含义和用途: • TDR(Transmit Data Register)&…

NB/T 32004-2018测试是什么,光伏并网逆变器NB/T 32004测试项目

NB/T 32004-2018测试是什么,光伏并网逆变器NB/T 32004测试项目 根据NB/T 32004-2018《光伏并网逆变器技术规范》,光伏并网逆变器的测试项目涵盖电气性能、安全保护、环境适应性、电磁兼容性及并网性能五大类,共42项核心测试内容。以下是关键测…

数据可视化——一图胜千言

第04篇:数据可视化——一图胜千言 写在前面:大家好,我是蓝皮怪!前面几篇我们聊了统计学的基本概念、数据类型和描述性统计,这一篇我们要聊聊数据分析中最直观、最有趣的部分——数据可视化。你有没有发现,很…