前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Python爬虫入门(二)

Python爬虫入门(二)

作者头像
小之丶
发布于 2018-03-07 06:47:23
发布于 2018-03-07 06:47:23
1.2K00
代码可运行
举报
文章被收录于专栏:WeaponZhiWeaponZhi
运行总次数:0
代码可运行

上一篇文章大概的讲解了 Python 爬虫的基础架构,我们对 Python 爬虫内部运行流程有了一定的理解了,我们这节将用一些简单的 Python 代码实现Python 爬虫架构的 URL 管理器、网页下载器和网页解析器。

URL 管理器

上篇文章我们已经说了,URL 管理器是用来管理待抓取的 URL 和已抓取的 URL,作为一只聪明的爬虫,我们当然应该会选择跳过那些我们已经爬取过的 URL ,这不仅是为了防止重复抓取,也为了防止一些循环抓取的问题,URL 间的互相调用会导致爬虫的无限死循环抓取。

URL 管理器就是为了解决这些问题而存在的,有了它,我们的爬虫才会更加聪明,从而避免重复抓取和循环抓取。上面列出的就是 URL 管理器所要做的工作,根据这些职能,我们就可以总结出实现 URL 管理器的一个大体思路。

我们需要两个容器 A 和 B,A 用来存储待爬取的 URL,B 用来存储已爬取的 URL,管理器从 A 中获取 URL 来交付给网页下载器去处理,如果 A 中没有 URL 就等待,每当爬虫爬取到新的 URL 的时候,就将这个 URL 添加到 A 中排队等待爬取。爬取完一个 URL 后,就把这个 URL 存放到 B 中。爬虫的时候,如果获取到的 URL 在 A 中或者 B 中存在了,就跳过该 URL。流程图如下:

以上功能是 URL 管理器需要实现功能的最小功能集合,复杂的情况当然具备的功能也更多。我们来看一下简单的 URL 管理器内存实现代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UrlManager(object):

   def __init__(self):
       self.new_urls = set()
       self.old_urls = set()

   def add_new_url(self,url):
       if url is None:
           return
       if url not in self.new_urls and url not in self.old_urls:
           #添加待爬取URL
           self.new_urls.add(url)
   
   def has_new_url(self):
       return len(self.new_urls) != 0

   def get_new_url(self):
       #获取并移除一个待爬取URL
       new_url = self.new_urls.pop()
       #将URL添加进已爬取URL
       self.old_urls.add(new_url)

上面的代码很简单,我们使用 Python 中的 Set 来作为容器管理 URL,因为它可以自动的进行去重处理而且内部的查询速度也是非常快速,所以很方便。获取待爬取 URL 的时候,我们使用 pop 方法,在获取一个元素的同时将它从 set 中移除出去,从而实现类似队列的排队形式。

这就是我们 URL 管理器的一个简单的实现方式了,虽然很简单,但基本功能思想已经包含在里面了。

网页下载器

网页下载器是将互联网上的 URL 对应的网页下载到本地的工具,当我们从 URL 管理器中获取到一个爬取 URL 的时候,我们只有将 URL 对应的网页下载到本地,才能继续后面的数据处理,所以网页下载器在爬虫架构中十分重要,是核心组件。

网页下载器的运行模式很简单,它可以将 URL 对应的网页以 HTML 的形式下载到本地,存储成一个本地文件或者以内存字符串的形式存储下来。总而言之就是下载一个静态网页文件,文件内容就是

这样的标签组成的 HTML 文件。

Python 中实现网页下载器有很多现成并且功能强大的库可供选择。urllib 是 Python 官方提供的基础模块,requests 是一个功能强大的第三方模块,我将使用 Python3 中的 urllib 作为演示。需要注意的是 urllib2 和 Python3 的 urllib 语法区别还是比较大的,大家权益好选择一个版本来进行学习。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#encoding:UTF-8
import urllib.request

url = "http://www.baidu.com"
data = urllib.request.urlopen(url).read()
data = data.decode('UTF-8')
print(data)

这是 urllib 最简单的使用方法,我们通过 urlopen 方法读取一个 URL,并调用 read 方法获取我们刚刚说到的 HTML 内存字符串,打印出来就是一堆标签格式的网页字符串了。

urlopen函数返回了一个HTTPResponse对象,这个对象挺有用的,是爬取请求的返回对象,我们可以通过它查看爬取 URL 请求的状态,还有一些对象信息等,比如 getcode 为 200 代表了网络请求成功。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a = urllib.request.urlopen(full_url)

>>> a.geturl()
'http://www.baidu.com/s?word=Jecvay'

>>> type(a)
<class 'http.client.HTTPResponse'>

>>> a.info()
<http.client.HTTPMessage object at 0x03272250>

>>> a.getcode()
200

当然了,我们的网络请求的实际情况是比较复杂的,有时候你需要在请求中添加数据,或者更改一下 header,urllib 的 Request 对象可以满足这些需求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import urllib.request

request = urllib.request.Request("http://www.baidu.com")
# 添加请求头
request.add_header('User-Agent', 'Mozilla/5.0')
# 添加数据
request.data = b"I am a data"

response = urllib.request.urlopen(request)

还有一些更加特殊的场景,比如有的网页需要 Cookie 处理,有的网页需要添加网页代理才能访问,有的网页需要输入账号密码验证,有的网页需要 HTTPS 协议才能访问。面对这些比较复杂的场景,urllib 提供了 Handler 这个强大的工具来处理这些需求。

不同的场景有不同的 Handler,比如处理 Cookie 使用 HTTPCookieProcessor ,处理网络代理可以使用 ProxyHandler,使用的时候,我们用 Handler 来构建一个 opener,然后用把 opener 安装到 request 上,这样再进行请求的时候,所安装的 Handler 就会起到处理特殊场景的作用。我们拿输入用户密码这种场景来举例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import urllib.request
# 构建基础HTTP账号验证Handler
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
                         uri='https://mahler:8092/site-updates.py',
                         user='klem',
                         passwd='kadidd!ehopper')
# Handler 构建 opener
opener = urllib.request.build_opener(auth_handler)
# 安装 opener
urllib.request.install_opener(opener)
urllib.request.urlopen('http://www.example.com/login.html')

我们利用多态构建了一个 HTTP 基本验证信息的 Handler,添加好相关的账号密码信息后,构建了一个 opener,并把 opener 安装到 request 上,在请求一个带有验证地址的时候,将会填充我们在 Handler 中填写的数据。

有关 urllib 的 API 大家可以参考 Python3 官方文档,文档写的清晰明了而且有官方的代码示例,我也阅读过文档,感觉 Python 官方的文档确实非常用心,很舒服。requests 这个第三方库大家可以自行了解下,刚开始学习的时候,实际上 urllib 基本能满足你的需求了。

网页解析器

网页下载器将网页下载到本地后,我们需要使用网页解析器从下载好的本地文件或者内存字符串中提取出我们需要的有价值信息。对于定向爬虫来说,我们需要从网页中提取两个数据,一个是我们需要的价值数据,另外就是该网页 URL 所能跳转的 URL 列表,这个列表我们将输入到 URL 管理器中进行处理。Python 中有以下几种方式可以实现网页解析器。

一个就是使用正则表达式,这个方式最为直观,我们将网页字符串通过正则的模糊匹配的方式,提取出我们需要的价值数据,这种方法虽然比较直观,但如果网页复杂,会比较麻烦。但我的建议,大家还是学一下正则表达式,这个毕竟是一门扛把子技术了,至少你得看得懂。

同时推荐大家另一款分析语言 XPATH,它是一门高效的分析语言,语法表达相比正则来说清晰简单,如果你掌握的好,基本可以替代正则,大家有兴趣可以搜索学习一下哦~

Python 还可以使用 html.parser,lxml,以及第三方库 BeautifulSoup 来进行网页解析。BeautifulSoup 本身包含了 html.parser 和 lxml,功能较为强大,它使用结构化解析来解析网页,结构化解析就是使用 DOM 树的方式进行上下级元素的遍历访问,从而达到解析和访问 HTML 文件的目的。一图理解

我们这里介绍下 BeautifulSoup,安装很简单,有好几种方法,最简单的方法就是使用命令 pip install beautifulsoup4 来安装,一些安装的流程和一些问题就不在这里多说了。

介绍下 BeautifulSoup 的使用方法,更加详细的 API 还是要看官方文档,而且 BS 的文档有友好的国人开发者在进行翻译,还是非常不错的~

使用 BS 的流程是,首先创建 BS 对象,传入对应的网页字符串,并指定相应的解析器(html.parser 或者 lxml),然后使用 find_all 或者 find 函数来进行搜索节点,最后通过获取到的节点访问对应的名称、属性或者文字,从而得到你想要的信息。

举个例子,现在有这样一个网页字符串信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<a href='123.html' class='article_link'> python </a>

在这段字符串里,节点的名称是 a,节点属性有 href='123.html' 和 class='article_link' 这两个,节点内容是 python。

有了这三个节点信息,我们就可以开始进行代码的编写了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from bs4 import BeautifulSoup

# 根据 HTML 网页字符串创建 BS 对象
soup = BeautifulSoup(
                    html_doc,            # HTML 字符串
                    'html.parser',       # HTML 解析器
                    from_encoding='utf8')# HTML 编码

# 查找所有标签为a的节点
soup.find_all('a')
# 查找所有便签为a,链接符合/view/123.htm形式的节点
soup.find_all('a',href='/view/123.htm')
# 查找所有标签为div,class为abc,文字为Python的节点
soup.find_all('div',class_='abc',string='Python')
# 使用正则表达式匹配
soup.find_all('a',href=re.compile(r'/view/\d+\.htm))

find_all 和 find 使用方法一致,只是 find_all 返回的是一个节点列表。注意到,find 方法是可以使用正则表达式进行模糊匹配的,这是它强大的地方,获取到节点 node,我们就可以很容易的获取到节点信息了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 得到节点:<a href='1.html'>Python</a>
# 获取节点标签名称
node.name
# 获取节点的href属性
node['href']
# 获取节点文字
node.get_text()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-01-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WeaponZhi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
爬虫入门实战课
写在最前 通过爬虫,可以搜集互联网上很多信息,有助于科研(比如爬个会议的网站之类的),因此想以应用带动一下学习,因此就有了这个小练手。 爬虫代码的主要结构 一个爬虫主要由四部分组成: 其中调度端相当于
用户1148523
2018/01/09
8280
爬虫入门实战课
一文带你了解Python爬虫(二)——四种常见基础爬虫方法介绍
–Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库 –urllib还是非常不方便的,而Requests它会比urllib更加方便,可以节约我们大量的工作。 –requests是python实现的最简单易用的HTTP库,建议爬虫使用requests库。 –默认安装好python之后,是没有安装requests模块的,需要单独通过pip安装
诡途
2020/10/16
1.4K0
Python爬虫抓取网站模板的完整版实现
下面分享下抓去网站模板的完整版实现,亲测可用。(注:仅限个人爱好者研究使用,不要用于其他非法用途。)
杨永贞
2022/10/04
1.6K0
Python爬虫抓取网站模板的完整版实现
我与Python爬虫的初次邂逅
自己一直喊着要学爬虫,但是总是因为各种各样的事情耽误了。最近感觉不能再颓废了,于是乎重新拾起来这个小小的目标,开始学习。
不会跳舞的鸟
2022/11/16
2360
【Python】Python爬虫爬取中国天气网(一)
最近想写一个爬取中国天气网的爬虫。所以打算写一个关于爬虫的系列教程,本文介绍爬虫的基础知识和简单使用。
树枝990
2020/08/19
2.8K0
【Python】Python爬虫爬取中国天气网(一)
Python 网络爬虫入门详解
网络爬虫又称网络蜘蛛,是指按照某种规则在网络上爬取所需内容的脚本程序。众所周知,每个网页通常包含其他网页的入口,网络爬虫则通过一个网址依次进入其他网址获取所需内容。
全栈程序员站长
2022/07/22
5250
Python 网络爬虫入门详解
Python爬虫实践——简单爬取我的博客
学任何一门技术,如果没有实践,技术就难以真正的吸收。利用上次博客讲解的三个知识点:URL 管理器、网页下载器和网页解析器来爬取一下我的博客。 我的博客地址 http://weaponzhi.online/ 这个博客里面没有技术的文章,主要是我的一些生活上面的记录,可以说是我的日记本,平时会写一些思想感悟,记录些琐事。我们简单以这个博客主页为入口,爬取一下以 weaponzhi.online 为 host 下所有的 URL 。 首先当然是需要一个 URL 管理器了,但和上篇文章说的有所不同,这次我们的待爬取数
小之丶
2018/03/07
1.1K0
Python爬虫实践——简单爬取我的博客
Python爬虫基础
Python非常适合用来开发网页爬虫,理由如下: 1、抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁;相比其他动态脚本语言,如perl,shell,python的urllib包提供了较为完整的访问网页文档的API。(当然ruby也是很好的选择) 此外,抓取网页有时候需要模拟浏览器的行为,很多网站对于生硬的爬虫抓取都是封杀的。这是我们需要模拟user agent的行为构造合适的请求,譬如模拟用户登陆、模拟session/cookie的存储和设置。在python里都有非常优秀的第三方包帮你搞定,如Requests,mechanize
用户7678152
2020/08/26
9890
Python2实现简单的爬虫
有时候我们需要一些网络数据来工作、学习,比如我们做深度学习的。当做一个分类任务时,需要大量的图像数据,这个图像数据如果要人工一个个下载的,这很明显不合理的,这是就要用到爬虫程序。使用爬虫程序帮我们下载所需要的图像。那么我们就开始学习爬虫吧。
夜雨飘零
2020/05/06
6310
03_多协程爬取糗事百科热图
今天在使用正则表达式时未能解决实际问题,于是使用bs4库完成匹配,通过反复测试,最终解决了实际的问题,加深了对bs4.BeautifulSoup模块的理解。
py3study
2020/01/17
5340
爬虫简介
爬虫的定义 爬虫:按照一定的规则,自动抓取互联网信息的程序或者脚本,从而获取对于我们有价值的信息。 爬虫的两大特征 能够按照作者的要求下载数据或者内容 能自动在网络上流窜 爬虫的三大步骤 下载网页 提取正确的信息 根据一定的规则自动跳到另外的网页上执行上两步 爬虫的分类 通用爬虫 专用爬虫(聚焦爬虫) 爬虫的结构 Python爬虫架构主要由五个部分组成,分别是调度器、URL管理器、网页下载器、网页解析器、应用程序(爬取的有价值数据)。 调度器:相当于一台电脑的CPU,主要负责调度URL管理器、下载器、解析器
人生不如戏
2018/05/30
6650
Python小姿势 - ## Python爬虫系列教程(一):简单的URL爬取
Python爬虫是一种使用脚本语言编写的网络爬虫程序。网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。爬虫程序从一个网页开始,根据网页中的链接抓取下一个网页,如此循环,直到抓取到所指定的信息为止。
不吃西红柿
2023/05/01
3610
使用Python的BeautifulSoup库实现一个可以爬取1000条百度百科数据的爬虫
BeautifulSoup安装很简单,我们可以直接使用pip来安装BeautifulSoup,安装命令如下:
端碗吹水
2020/09/23
2.5K0
使用Python的BeautifulSoup库实现一个可以爬取1000条百度百科数据的爬虫
Python爬虫入门知识!
Python现在非常火,语法简单而且功能强大,很多同学都想学Python!所以小的给各位看官们准备了高价值Python学习视频教程及相关电子版书籍,欢迎前来领取!
python学习教程
2019/07/10
5350
Python爬虫入门知识!
Python抓取数据_python抓取游戏数据
本文整理自慕课网《Python开发简单爬虫》,将会记录爬取百度百科“python”词条相关页面的整个过程。
全栈程序员站长
2022/09/20
2K0
Python爬虫|你真的会写爬虫吗?
咱们直接进入今天的主题---你真的会写爬虫吗?为啥标题是这样,因为我们日常写小爬虫都是一个py文件加上几个请求,但是如果你去写一个正式的项目时,你必须考虑到很多种情况,所以我们需要把这些功能全部模块化,这样也使我们的爬虫更加的健全。
AI算法与图像处理
2019/05/22
6000
Python爬虫|你真的会写爬虫吗?
爬虫入门(一):轻量级爬虫
其中,内存适合个人,缓存数据库适合大型公司。 ### 4.网页下载器(urllib2)[核心组件]() - 网页下载器:将互联网上URL对应的网页下载到本地的工具。 - Python有那几种网页下载器? -
一点儿也不潇洒
2018/08/07
4490
爬虫入门(一):轻量级爬虫
Python基础学习_09_网页爬虫基础
Python进行网页内容的爬取,首先需要将网页内容下载到本地,再针对特定网页内容的结构进行网页内容的解析,获得需要的数据。
码农帮派
2020/04/01
5270
Python基础学习_09_网页爬虫基础
python网络爬虫(9)构建基础爬虫思路
基础爬虫分5个模块,使用多个文件相互配合,实现一个相对完善的数据爬取方案,便于以后更完善的爬虫做准备。
嘘、小点声
2019/07/31
7620
Python3网络爬虫(七):使用Beautiful Soup爬取小说
本文总结了一些常见的网络爬虫和反爬虫技术,并介绍了一种基于Python的爬虫程序。该爬虫程序可以爬取指定网站的文章内容,并支持对某些网站的反爬虫策略。同时,还介绍了一种基于Web的爬虫程序,该程序可以爬取网站的文章列表,并支持对某些网站的反爬虫策略。
Jack_Cui
2018/01/08
4.5K0
Python3网络爬虫(七):使用Beautiful Soup爬取小说
相关推荐
爬虫入门实战课
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验