Python的网络爬虫框架-网络爬虫的常用技术
一、前言
- 个人主页: ζ小菜鸡
- 大家好我是ζ小菜鸡,让我们一起来学习Python的网络爬出框架-网络爬虫的常用技术。
- 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)
二、Python 的网络请求
URL 地址和下载网页,这两项是网络爬虫必备而又关键的功能,说到这两个功能必然离不开与HTTP 打交道了。本文将介绍在python中实现HTTP网络请求常见的三种方式:urllib、urllib3以及requests。
1.urllib模块
urllib是python自带模块,该模块中提供了一个urlopen()方法,通过该方法指定URL 发送网络请求来获取数据。urllib提供了多个子模块,具体模块名称与含义如下表所示:
模块名称 | 描述 |
---|---|
urllib.request | 该模块定义了打开URL (主要是HTTP)的方法和类,例如,身份验证,重定向,cookie等等。 |
urllib.error | 该模块中主要包含异常类,基本的异常类URLError。 |
urllib.parse | 该模块定义的功能分为两大类:URL 解析和URL 引用。 |
urllib.robotparser | 该模块用于解析robots.txt文件。 |
通过urlli b.request模块实现发送请求并读取网页内容的简单示例如下:
import urllib.request # 导入该模块
# 打开指定需要爬取的网页
response = urllib.request.urlopen("http://www.baidu.com")
html = response.read() # 读取网页代码
print(html) # 打印读取内容
上面的示例中,是通过get请求方式获取百度的网页内容。下面通过使用urlli b.request模块的post请求实现获取网页信息的内容,示例如下:
import urllib.request
import urllib.parse
# 将数据使用urlencode编码处理后,再使用encoding设置为utf-8编码
data = bytes(urllib.parse.urlencode({
"word": "holle"}), encoding="utf8")
# 打开指定需要爬取的网页
response = urllib.request.urlopen("http://httpbin.org/post", data=data)
html = response.read() # 读取网页代码
print(html) # 打印读取内容
说明: 这里通过 http://httpbin.org/post 网站进行演示,该网站可以作为练习使用urllib模块的一个站点使用,可以模拟各种请求操作。
2.urllib3 模块
urllib3是一个功能强大、条理清晰、用于HTTP 客户端的Python库,许多Python的原生系统已经开始使用urllib3 。urllib3提供了很多python标准库里所没有的重要特性:
- 线程安全
- 连接池
- 客户端SSL/TLS验证
- 使用多部分编码上传文件
- Helpers用于重试请求并处理HTTP重定向
- 支持gzip和deflate编码
- 支持HTTP和SOCKS代理
- 100%的测试覆盖率
通过urllib3模块实现发送网络请求的示例代码如下:
import urllib3
# 创建PoolManager对象,用于处理与线程池的连接以及线程安全的所有细节
http = urllib3.PoolManager()
# 对需要爬取的网页发送请求
response = http.request("GET", "https://www.baidu.com/")
print(response.data) # 打印读取内容
post请求实现获取网页信息的内容,关键代码如下:
对需要爬取的网页发送请求
response = http.request("POST",
"http://httpbin.org/post"
, fields={
"word": "hello"})
注意: 在使用urllib3模块前,需要在python中通过“pip install urllib3”代码进行模块的安装。
3.requests模块
requests是Python中实现HTTP请求的一种方式,requests是第三方模块,该模块在实现HTTP请求时要比urllib模块简化很多,操作更加人性化。在使用requests模块时需要通过执行pip install requests代码进行该模块的安装。requests功能特性如下:
- Keep-Alive & 连接池
- 国际化域名和URL
- 带持久Cookie的会话
- 浏览器式的SSL认证
- 自动内容解码
- 基本/摘要式的身份认证
- 优雅的Key/value Cookie
- 自动解压
- Unicode响应体
- HTTP(S)代理支持
- 文件分块上传
- 流下载
- 连接超时
- 分块请求
- 支持 .netrc
以 GET 请求方式为例,打印多种请求信息的示例代码如下:
mport requests
response = requests.get("http://www.baidu.com")
print(response.status_code) # 打印状态码
print(response.url) # 打印请求url
print(response.headers) # 打印头部信息
print(response.cookies) # 打印cookies信息
print(response.text) # 以文本形似打印网页源码
print(response.content) # 以字节流的形式打印网页源码
以POST请求方式,发送HTTP网络请求的示例代码如下:
import requests
data = {"word": "holle"} # 表单参数
# 对需求爬取的网页发送请求
response = requests.post("http://httpbin.org/post", data=data)
print(response.content) # 以字节流的形式打印网页源码
如果发现请求的URL 地址中参数是跟在?(问号)的后面,例如,httpbin.org/get?key=val。Requests模块提供了传递参数的方法,允许使用params关键字参数,以一个字典来提供这些参数。例如,想传递“key1=value1"和“key2=value2”到“httpbin.org/get”,可以使用下面代码:
import requests
payload = {"key1": "value1", "key2": "value2"} # 传递的参数
# 对需要爬取的网页发情请求
response = requests.get("http://httpbin.org/get", params=payload)
print(response.content) # 以字节流的形似打印网页源码
三、请求 headers 处理
有时在请求一个网页内容时,发现无论通过GET或者是POST以及其他请求方式,都会出现403错误。这种现象多数是由于服务器拒绝了您的访问,那是因为这些网页为了防止恶意采集信息,所使用的反爬虫设置。此时可以通过模拟浏览器的头部信息来进行访问,这样就能解决以上反爬设置的问题。下面以requests 模块为例介绍请求头部headers的处理,具体步骤如下:
(1)通过浏览器的网络监视器查看头部信息,首先通过谷歌浏览器打开对应的网页地址,然后快捷键<Ctrl+Shift+I>打开网络监视器,刷新当前页面,网络监视器将显示如下图所示的数据变化。
(2)选中第一条信息,右侧的信息头面板中将显示请求头部信息,然后复制该信息,如下图所示:
(3)实现代码,首先创建一个需要爬取的URL地址,然后创建headers头部信息,再发送请求等待响应,最后打印网页代码信息。实现代码如下:
import requests
url = "https://www.baidu.com/" # 创建需要爬取的网页地址
# 创建头部信息,根据当前浏览器版本进行复制即可
headers = {"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"}
response = requests.get(url, headers=headers) # 发起网络请求
print(response.content) # 以字节流形式打印网页源码
四、网络超时
在访问一个网页时,如果该网页长时未响应,系统就会判断该网页超时,所以无法打开网页。下面通过代码来模拟一个网络超时现象,代码如下:
mport requests
# 循环发送请求50次
for a in range(1, 50):
try:
# 设置超时为0.5秒
response = requests.get("https://www.baidu.com/", timeout=0.5)
print(response.status_code) # 打印状态码
except Exception as e:
print("异常" + str(e)) # 打印异常信息
打印结果如下图所示:
说明: 上面的代码中,模拟进行了50次循环请求,并设置了超时的时间为0.5秒,所以如果在0.5秒内服务器未响应将视为超时,将超时信息打印在控制台中。根据上述的模拟测试结果,可以确认在不同的情况设置不同的timeout值。
说起异常信息,requests模块同样提供了三种常见的异常类,示例代码如下:
import requests
# 导入requests.exceptions中的三个异常类
from requests.exceptions import ReadTimeout, HTTPError, RequestException
for a in range(1, 50):
try:
# 设置超时为0.5秒
response = requests.get("https://www.baidu.com/", timeout=0.5)
print(response.status_code) # 打印状态码
except ReadTimeout: # 超时异常
print("timeout")
except HTTPError: # HTTP异常
print("httperror")
except RequestException: # 请求异常
print("reqerror")
五、代理服务
在爬取网页的过程中,经常会出现不久前可以爬取的网页现在不可以爬取,这因为您的IP 被反爬取网站的服务器所屏蔽了。此时代理服务可以为您解决这一麻烦,设置代理时,首先需要找到代理地址,例如,“122.114.43.113”,对应端口号为“808”,完整的格式为“122.114.43.113:808”。示例代码如下:
import requests
proxy = {"http": "122.114.43.113:808", "https": "122.114.43.113:808"} # 设置代理IP和对于端口号
# 对需要爬取的网页进行请求
response = requests.get("https://www.baidu.com/", proxies=proxy)
print(response.content) # 以字节流形式打印网页源码
注意: 由于示例中的代理IP是免费的,所以使用的时间不固定,超出使用时间范围内该地址将失效,在地址失效时或者地址错误时,控制太将显示如下图所示的错误信息:
六、HTML 解析之 BeautifulSoup
BeautifulSoup是一个用于从HTML和XML文件中提取数据的Python库。BeautifulSoup提供一些简单的函数来处理导航、搜索、修改分析树等功能。BeautifulSoup模块中的查找提取功能非常强大,而且非常便捷,可以节省程序员数小时或数天的时间。
1.BeautifulSoup的安装
在https://www.crummy.com/software/BeautifulSoup/bs4/download/下载BeatifulSoup的源码,进cmd中,进入BeatifulSoup4-4.8.0的存储路径,在输入Python steup.py install命令即可。
2.BeatifulSoup的使用
BeatifulSoup 安装完成以后,下面将介绍如何通过BeatifulSoup进行HTML的解析工作,其具体示例步骤如下:
(1)导入bs4库,然后创建一个模拟HTML代码的字符串,代码如下:
from bs4 import BeautifulSoup #导入BeatifulSoup 库
#创建模拟HTML代码的字符串
html_doc = """
<html><head><title>The Dotmouse's story</title></head>
<body>
<p class="title"><b>The Dotmouse's story</b></p>
<p class="story">Once upon a time there were three little sisiter ;and therinames were
<a href ="http ://example.com/elsie" class ="sister" id ="link1">Elsie</a>,
<a href ="http ://example.com/lacie" class ="sister" id ="link2">Lasie</a> and
<a href ="http ://example.com/tillie" class ="sister" id ="link3">Tillie</a>;
and they lived at the bottom of a well. </p>
<p class ="story">...</p>
"""
(2)创建一个eautifulSoup对象,并指定解析器为lxml,最后通过打印的方式将解析器的HTML 代码显示在控制台中,代码如下:
import lxml
#创建一个BeatifulSoup对象,获取页面正文
soup = BeautifulSoup(html_doc,features="lxml")
print(soup) #打印解析的HTML代码
运行结果如下图所示:
说明:如果将html_doc字符串中的代码,保存在index.html文件中,可以通过打开HTML文件的方式进行代码的解析,并且可以通过prettify()方法进行代码的格式化处理,代码如下所示:
# 创建一个BeatifulSoup对象打开需要解析的html文件
soup = BeautifulSoup(open("index.html"), "lxml")
print(soup.prettify()) # 打印格式化后的代码
Python的网络爬出框架-网络爬虫的常用技术的介绍,到此就结束了,感谢大家阅读,如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)