Python的爬虫框架主要可以分为以下五个部分:

爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义;

URL管理器:负责URL的管理,包括带爬取和已爬取的URL、已经提供相应的接口函数(类似增删改查的函数)

网页下载器:负责通过URL将网页进行下载,主要是进行相应的伪装处理模拟浏览器访问、下载网页

网页解析器:负责网页信息的解析,这里是解析方式视具体需求来确定

信息采集器:负责将解析后的信息进行存储、显示等处理


代码示例是爬取CSDN博主下的所有文章为例,文章仅作为笔记使用,理论知识rarely

一、网页解析器简介

      解析器的工作就是按需求对网页进行解析,并将解析信息进行处理。

      解析器可以选择的工具有很多种,在这个博客里使用的时BeautifulSoup + 正则表达式进行信息的提取。BeautifulSoup使用起来比较方便(其他的目前还不会,没接触) ,因为不熟,所以不做技术说明,近将经过尝试的结果呈现。

二、网页解析器示例:(爬取CSDN博主下的所有文章

# author : sunzd
# date : 2019/3/22
# position: chengdu from bs4 import BeautifulSoup
from urllib import error
import re class HtmlParser(object):
def __init__(self):
# self.articles = {}
# self.articles_url = set()
# self.articles_title = set()
# self.articles_date = set()
self.url_page = None '''
print(link.parent.span) :
<span class="article-type type-1">原</span>
print(link.parent.span.text) :
节点span的内容:原
print(link.parent.get('href')) :
https://blog.csdn.net/s2603898260/article/details/85067018
https://blog.csdn.net/s2603898260/article/details/85020006
'''
'''
get_article_urls最后的结果只获取了文章的URL,其中大部分代码为调试记录,没删除
'''
def get_article_urls(self, page_url, soup):
# 1. 根据文章类型来确定文章信息
# links = soup.find_all('span', class_=re.compile(r"article-type type-[0-9]"))
# article_titles = soup.find_all('div', attrs={'class':"article-item-box csdn-tracking-statistics",'data-articleid':"\d+"})
# article_info = soup.find_all('div', class_="info-box d-flex align-content-center") '''
<div>
--< h4 >
--< p >
--< div >
links = soup.find_all('div', attrs={'class':"article-item-box csdn-tracking-statistics"})
# 获取文章标题信息
print(links[0].h4) # ok
# 获取文章简介信息
print(links[0].div.p)
# 获取文章发表时间、阅读量信息
for child in links[0].div.children:
if len(child) != 3: # 去除空的子标签
continue
print(child.span.text) # print(child.span)
if len(links) > 0:
for link in links:
print(link.next_sibling.next_sibling.next_sibling.next_sibling)
print(link)
print("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-")
'''
articles_url = set()
links = soup.find_all('div', attrs={'class':"article-item-box csdn-tracking-statistics"})
if len(links) > 0:
for link in links:
try:
if link.attrs['style']: # 去除第一个不属于该博主的链接
continue
except KeyError as e:
articles_url.add(link.h4.a.get('href')) # ******文章链接******
# print(link.h4.a.attrs['href']) #get attrs在此等价
# tmp = link.h4.a.text
# tmp = tmp.replace("原", "")
# tmp = tmp.replace("转", "")
# tmp = tmp.replace("\n", "")
# self.articles_title.add(tmp.replace(" ", "")) # 文章标题
# for child in link.div.children:
# if len(child) != 3: # 去除空的子标签
# continue
# # print(child.span.text) # print(child.span)
# self.article_date.add() # self.articles = dict(zip(self.articles_url, self.articles_title)) 将两个列表合并为字典
# tmp = self.articles_url.pop()
# print(self.articles_url)
# print("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-") return articles_url '''
第一页:
<li data-page="1" class="ui-pager focus">1</li>
<li class="js-page-next js-page-action ui-pager">下一页</li>
<li class="js-page-last js-page-action ui-pager"></li>
第二页:
<li data-page="2" class="ui-pager focus">2</li>
<li class="js-page-next js-page-action ui-pager ui-pager-disabled">下一页</li>
<li class="js-page-last js-page-action ui-pager ui-pager-disabled"></li>
'''
def get_page_url(self, page_url, soup):
if page_url is None or soup is None:
return None # https://blog.csdn.net/s2603898260/article/list/1?
# 获取当前页
cur_page = soup.find('li', attrs={'class':"ui-pager focus"}) #attrs={'class':"ui-pager focus"}
print(cur_page)
# 判断是否有下一页
# links = soup.find('li', class_=re.compile(r"js-page-last.+ui-pager-disabled"))
links = soup.find('li', class_="js-page-next js-page-action ui-pager ui-pager-disabled") if links is None or len(links) == 0:
self.url_page = None
return self.url_page
# 寻找下一页
# TODO: return self.url_page def parser(self, page_url, html):
if html is None or page_url is None:
print("html or page_url is None")
return None
soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')
articles = self.get_article_urls(page_url, soup)
#new_page = self.get_page_url(page_url, soup) return articles

三、上述代码用到的知识点:

1. BeautifulSoup Note:

soup = BeautifulSoup(html, 'html.parser', from_encoding='utf-8')      # 将html转换为标记树的形式soup

使用find_all()寻找符合属性的所有节点信息:

article_titles = soup.find_all('div', attrs={'class':"article-item-box csdn-tracking-statistics",'data-articleid':"\d+"})

可以使用find()寻找符合属性的第一个节点信息,一般这个节点为大节点.(以下为假设)

 如博客的正文节点<div>,可以先通过find找到<div>, 然后在一次遍历其他的节点、寻找所有符合要求的图片等 
# find('div',attrs={}).find_all('p',attrs={})
# <div>
 # ----< h4 >
 # ----< p >
 # ----< div >  
# ---------< p >
# ---------< p >
# ---------< p > # 获取文章标题信息
print(links[0].h4) # ok
# 获取文章简介信息
print(links[0].div.p)
# 获取文章发表时间、阅读量信息
for child in links[0].div.children:
if len(child) != 3: # 去除空的子标签
continue
# print(child.span.text) #打印节点文本信息
# print(child.span) #打印整个节点信息

打印节点属性信息:

# print(link.h4.a.get('href'))    # 文章链接
# print(link.h4.a.attrs['href']) # 文章链接 两个等价

python3 爬虫五大模块之四:网页解析器的更多相关文章

  1. python3 爬虫五大模块之五:信息采集器

    Python的爬虫框架主要可以分为以下五个部分: 爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义: URL管理器:负责URL的管理,包括 ...

  2. python3 爬虫五大模块之三:网页下载器

    Python的爬虫框架主要可以分为以下五个部分: 爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义: URL管理器:负责URL的管理,包括 ...

  3. python3 爬虫五大模块之二:URL管理器

    Python的爬虫框架主要可以分为以下五个部分: 爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义: URL管理器:负责URL的管理,包括 ...

  4. python3 爬虫五大模块之一:爬虫调度器

    Python的爬虫框架主要可以分为以下五个部分: 爬虫调度器:用于各个模块之间的通信,可以理解为爬虫的入口与核心(main函数),爬虫的执行策略在此模块进行定义: URL管理器:负责URL的管理,包括 ...

  5. 第6章 网页解析器和BeautifulSoup第三方插件

    第一节 网页解析器简介作用:从网页中提取有价值数据的工具python有哪几种网页解析器?其实就是解析HTML页面正则表达式:模糊匹配结构化解析-DOM树:html.parserBeautiful So ...

  6. python 之网页解析器

    一.什么是网页解析器 1.网页解析器名词解释 首先让我们来了解下,什么是网页解析器,简单的说就是用来解析html网页的工具,准确的说:它是一个HTML网页信息提取工具,就是从html网页中解析提取出“ ...

  7. Python 网页解析器

    Python 有几种网页解析器? 1. 正则表达式 2.html.parser (Python自动) 3.BeautifulSoup(第三方)(功能比较强大) 是一个HTML/XML的解析器 4.lx ...

  8. 爬虫笔记(四)------关于BeautifulSoup4解析器与编码

    前言:本机环境配置:ubuntu 14.10,python 2.7,BeautifulSoup4 一.解析器概述 如同前几章笔记,当我们输入: soup=BeautifulSoup(response. ...

  9. Python模块:配置文件解析器configparser

    版权声明:本文为博主皮皮http://blog.csdn.net/pipisorry原创文章,未经博主同意不得转载. https://blog.csdn.net/pipisorry/article/d ...

随机推荐

  1. 总结开发中基于DevExpress的Winform界面效果

    DevExpress是一家全球知名的控件开发公司, DevExpress 也特指此公司出品的控件集合或某系列控件或其中某控件.我们应用最为广泛的是基于Winform的DevExpress控件组,本篇随 ...

  2. Maven-内部多个项目依赖自动升级版本的部署

    需要自动升级版本的AAA项目发布 (有内部依赖时) 步骤比较复杂, 有一些需要根据实际情况调整. 考虑了以下几种可能性: 依赖模块的版本有更新 依赖模块版本没更新 依赖模块的版本号: 直接定义, 用属 ...

  3. .NET5控制台程序使用EF连接MYSQL

    .NET5控制台程序使用EF连接MYSQL 1.使用nuget下载: Microsoft.Extensions.Configuration.Json Pomelo.EntityFrameworkCor ...

  4. 关于Asp.Net MVC html.renderaction传递参数

    View视图 @{html.renderaction("控制器方法名","控制器名称",new{params1="参数值"})} Contr ...

  5. MySQL Schema 与数据类型优化

    良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询语句来设计schema,这往往需要权衡各种因素. 例如,反范式的设计可以加快某些类型的查询,但同时可能使另一些类型的查询变慢:添加计数 ...

  6. 我,Android开发5年,32岁失业,现实给我狠狠上了一课!

    如今的职场,风险是越来越高,不管你是应届生或者你是否中年,遇到好点的企业,红火那么做个三五年,运气不好,半年甚至2.3个月也就玩完了. 所以,即使你希望工作能稳定,但也会让你大失所望,职场寿命就那么几 ...

  7. PAT甲级 1112 Stucked Keyboard

    题目链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805357933608960 这道题初次写的时候,思路也就是考虑 ...

  8. Dockerfile 多阶段构建实践

    写在前面 在Docker Engine 17.05 中引入了多阶段构建,以此降低构建复杂度,同时使缩小镜像尺寸更为简单.这篇小作文我们来学习一下如何编写实现多阶段构建的Dockerfile 关于doc ...

  9. 依赖注入@Autowired@Primary@Quelifier使用

    @Autowired 注入声明的SpringBean对象,根据一定的规则首先按照注入的类型去查找,如果没有找到安装注入的名称去匹配你要注入的属性名称,如果都没有找到启动项目时抛出异常,@Autowir ...

  10. Longhorn,企业级云原生容器分布式存储 - 定制默认设置

    内容来源于官方 Longhorn 1.1.2 英文技术手册. 系列 Longhorn 是什么? Longhorn 云原生容器分布式存储 - 设计架构和概念 Longhorn 云原生容器分布式存储 - ...