百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

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跨端框架的代练系统,通过智能匹配与安全护航两大核心策略,能够有效提升用户信任,构建健康可持续的代练生态。以下从技术实现与用户体...

取消回复欢迎 发表评论: