Python爬虫进阶教程(六):爬虫基础架构及流程
ccwgpt 2024-09-29 09:59 37 浏览 0 评论
基础架构和流程
简单的爬虫架构由以下几部分构成:
- 爬虫调度器:总体协调其它几个模块的工作
- URL管理器:负责管理URL,维护已经爬取的URL集合和未爬取的URL集合
- 网页下载器:对未爬取的URL下载
- 网页解析器:解析已下载的html,并从中提取新的URL交给URL管理器,数据交给存储器处理
- 数据存储器:将html解析出来的数据进行存取
架构图如下:
爬虫流程图如下:
下面我们就分别按每个部分来拆分。
我们本次就拿百科搜索词条来演示,爬取百科内容标题和摘要信息,同时如果摘要中有链接,还会把连接的标题摘要下载下来。如下图:
URL管理器
基本功能:
- 判断是否有待爬取的url
- 添加新的url到待爬取url集合中
- 获取未爬取的url
- 获取待爬取集合大小
- 获取已爬取集合大小
- 将爬取完成的url从待爬取url集合移动到已爬取url集合。
这里URL管理器还要用到set去重功能,防止程序进入死循环。大型互联网公司,由于缓存数据库的高性能,一般把url存储在缓存数据库中。小型公司,一般把url存储在内存中,如果想要永久存储,则存储到关系数据库中。
URL管理器代码
class UrlManager: """ URL管理器类 """ ? def __init__(self): """ 初始化未爬取集合new_urls和已爬取集合old_urls """ # python的set和其他语言类似, 是一个无序不重复元素集 self.new_urls = set() self.old_urls = set() ? def has_new_url(self): """ 判断是否有未爬取的url :return: """ return self.new_url_size() != 0 ? def get_new_url(self): """ 获取未爬取的url :return: """ new_url = self.new_urls.pop() self.old_urls.add(new_url) return new_url ? def add_new_url(self, url): """ 将新的url添加到未爬取的url集合中 :return: """ if url is None: return # 判断url是否在new_urls或old_urls中 if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) ? def add_new_urls(self, urls): """ 添加新的url到未爬取集合 :param urls: url集合 :return: """ if urls is None or len(urls) == 0: return # 循环将获取的url存入new_urls中 for url in urls: self.add_new_url(url) ? def new_url_size(self): """ 获取未爬取集合大小 :return: """ return len(self.new_urls) ? def old_url_size(self): """ 获取已爬取集合大小 :return: """ return len(self.old_urls)
HTML下载器
HTML下载器就比较简单了,只是通过requests获取html内容即可(注意:要用到session,不然会报 TooManyRedirects 异常),具体看代码:
import requests ? class HtmlDownload: """ HTML下载器类 """ ? def download(self, url): """ 下载html :param url:根据url下载html内容 :return: 返回html """ # 创建session对象,这里一定要用session,不然会报TooManyRedirects异常 s = requests.session() # 添加头部信息 s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0' # 获取内容 resp = s.get(url) # 要以content字节形式返回 return resp.content.decode()
HTML解析器
先来分析要爬取的网页:
通过上面分析可以看到,我们需要的标题在<dd class="lemmaWgt-lemmaTitle-title">标签中,摘要信息在<div class="para" label-module="para">标签中,其中<div class="para" label-module="para">标签中的a标签的herf是我们需要继续爬取的相对url通过上面分析可以看到,我们需要的标题在<dd class="lemmaWgt-lemmaTitle-title">标签中,摘要信息在<div class="para" label-module="para">标签中,其中<div class="para" label-module="para">标签中的a标签的herf是我们需要继续爬取的相对url。
from bs4 import BeautifulSoup ? class HtmlParse: """ HTML解析器类 """ ? def __init__(self, baseurl='https://baike.baidu.com'): """ 初始化基础url :param baseurl:基础url """ self.baseurl = baseurl ? def parse_data(self, page): """ 获取网页数据 :param page:获取的html :return:解析后要存储的数据 """ # 创建实例 soup = BeautifulSoup(page, 'lxml') # 获取标题 title = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1').string # 获取摘要 summary = soup.find('div', class_='para').text # 完整的数据信息 data = title + summary return data ? def parse_url(self, page): """ 获取网页url :param page:获取的html :return:解析后获取的新url """ # 创建实例 soup = BeautifulSoup(page, 'lxml') # 所有的<div class="para" label-module="para">中a标签 anodes = soup.find('div', class_='para').find_all('a') # new_url set集 new_urls = set() # 循环获取相对路径(href),与baseurl拼成全url for anode in anodes: link = anode.get('href') # 完整路径 fullurl = self.baseurl + link # 添加到未爬取集合new_urls中 new_urls.add(fullurl) return new_urls
数据存储器
解析出来的数据就直接追加保存到文件就可以了。
class DataStore: """ 数据存储器类 """ ? def store_data(self, data, name='baike.txt'): """ 将获取的数据存储到文件中 :param data: 解析的数据 :param name: 本地文件名 :return: """ with open(name, 'a', encoding='utf-8') as fp: fp.write('\r\n') fp.write(data)
爬虫调度器
爬虫调度器主要负责以上几个模块的调度
from spider.Datastore import DataStore from spider.Htmldownload import HtmlDownload from spider.Htmlparse import HtmlParse from spider.Urlmanager import UrlManager ? class SpiderMain: """ 爬虫调度器类 """ ? def __init__(self): """ 初始化各模块 """ self.manager = UrlManager() self.download = HtmlDownload() self.parse = HtmlParse() self.output = DataStore() ? def spider(self, url): """ 爬虫主程序 :param url:初始url :return: """ # 添加初始url到未爬取的new_urls中 self.manager.add_new_url(url) # 通过while循环获取是否还有新的url要爬取,爬取了5条就结束,防止死循环下去 while self.manager.has_new_url() and self.manager.old_url_size() < 5: try: # 获取url new_url = self.manager.get_new_url() # 获取html html = self.download.download(new_url) # 解析后的新url new_urls = self.parse.parse_url(html) # 解析后要存储的数据 data = self.parse.parse_data(html) # 添加解析后的新url到new_urls集中 self.manager.add_new_urls(new_urls) # 保存数据 self.output.store_data(data) print('已经抓取%s 个链接' % self.manager.old_url_size()) except Exception as e: print('failed') print(e) ? if __name__ == '__main__': # 实例化爬虫调度器类 spidermain = SpiderMain() # 输入初始url进行爬取 spidermain.spider('https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB')
运行结果(只爬取了5条):
已经抓取1 个链接 已经抓取2 个链接 已经抓取3 个链接 已经抓取4 个链接 已经抓取5 个链接
好,今天的爬虫基础框架,就到这里了。
相关推荐
- Android开发基础入门(一):UI与基础控件
-
Android基础入门前言:从今天开始,我们开始分享Android客户端开发的基础知识。一、工具指南工欲善其事必先利其器,我们首先介绍一下开发Android常用的集成开发环境。小雨在上大学期间,开发a...
- 谷歌Material Design质感设计UI开发框架
-
谷歌MaterialDesign质感设计是一个新的用户界面设计概念,即将到来的Android版本称为“AndroidL”中会使用这种设计语言。在这篇文章中,我们收集出最新的和最好的Android...
- Android主流UI开源库整理(android 开源ui)
-
前言最近老大让我整理一份Android主流UI开源库的资料,以补充公司的Android知识库。由于对格式不做特别限制,于是打算用博客的形式记录下来,方便查看、防丢并且可以持续维护、不断更新。标题隐...
- 系统工具类App的开发框架(系统开发方法工具)
-
系统工具类App的开发框架选择,很大程度上取决于目标平台(Android、iOS或两者兼有),以及对性能、系统级访问深度和开发效率的需求。由于这类App常常需要深入操作系统底层,因此原生开发框架通常是...
- 2025年vue前端框架前瞻(vue前端开发规范手册)
-
Vue是一个轻量且灵活的JavaScript框架,广受开发者喜爱,因其简单易用的API和组件化的开发方式而闻名。Vite是一个现代化的前端构建工具,以其极快的开发服务器启动速度和热模块替换...
- 前端流行框架Vue3教程:28. Vue应用
-
28.Vue应用应用实例每个Vue应用都是通过createApp函数创建一个新的应用实例main.jsimport{createApp}from'vue'import...
- 2024 Vue 最全的生态工具组合推荐指南
-
Vue3虽然Vue2很多项目在用,但是官方已经宣布不再维护Vue2,所以新项目肯定首选Vue3来进行开发,组合式API开发起来比选项式API方便多了,而且Vue3的响应式实现也更...
- 基于 Vue3 Element Plus 的中后台管理系统模板
-
PureAdmin是一个开源的前端中后台管理系统模板,基于Vue3、Element-Plus,支持移动端、国际化、多主题设置,支持前端静态路由、后端动态路由配置,旨在为开发人员提供一个易于使用、高...
- 重磅!滴滴开源全新跨端小程序框架,基于 Vue 3!
-
最近,滴滴出行开源了自主研发的全新轻量级跨端小程序框架——星河(Dimina),为开发者提供了“一次开发,多端运行”的高性能、低门槛解决方案。下面就来一览Dimina的魅力!什么是星河(Dim...
- 【推荐】一款基于 Vue + .NET 8 开源、免费、功能强大的快速开发框架
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍Vue.NetCore是一款集高效、灵活、易于扩展于一体的快速开发框架(基于Vue提供Vue2/Vue...
- 搭建Trae+Vue3的AI开发环境(vue ide 开发工具)
-
从2024年2025年,不断的有各种AI工具会在自媒体中火起来,号称各种效率王炸,而在AI是否会替代打工人的话题中,程序员又首当其冲。作为一个后端开发,这篇文章基于Trae工具,来创建和运行一个简单的...
- 一款基于 Vue + .NET 8 开源、免费、功能强大的快速开发框架
-
项目介绍Vue.NetCore是一款集高效、灵活、易于扩展于一体的快速开发框架(基于Vue提供Vue2/Vue3版本和.NET8前后端分离),适用于多种应用场景。通过前后端分离的设计、强大的...
- 盘点一下这些年PHP在桌面应用方面的解决方案
-
今天作者给大家盘点一下近些年PHP在实现桌面客户端方面的项目。PHP-GTKPHP-GTK是2001年3月创立,是PHP的一个扩展,实现了与GTK+的绑定,提供面向对象的接口,极大地简化了客户端跨平台...
- PHP+Uniapp校园圈子系统校园论坛小程序开发:踩坑与优化经验分享
-
一、系统架构与技术选型1.架构设计采用前后端分离架构,前端使用Uniapp实现跨端开发(支持微信小程序、H5、App),后端基于PHP(推荐ThinkPHP或Laravel框架)提供RESTful...
- 智能匹配+安全护航:PHP代练系统护航小程序如何提升用户信任?
-
在代练行业中,用户信任是平台发展的核心要素。基于PHP后端与uni-app跨端框架的代练系统,通过智能匹配与安全护航两大核心策略,能够有效提升用户信任,构建健康可持续的代练生态。以下从技术实现与用户体...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)