1. 认识爬虫是什么
概念
网络爬虫又称网络蜘蛛、网络机器人
,它是一种按照一定的规则
自动浏览、检索网页信息的程序或者脚本。
网络爬虫能够自动请求网页
,并将所需要的数据抓取
下来。通过对抓取的数据进行处理
,从而提取出有价值的信息
。
分类
通用网络爬虫、聚焦网络爬虫、增量式网络爬虫。
通用网络爬虫:是搜索引擎的重要组成部分,上面已经进行了介绍,这里就不再赘述。通用网络爬虫需要遵守 robots 协议
,网站通过此协议告诉搜索引擎哪些页面可以抓取,哪些页面不允许抓取
。
robots 协议:是一种“约定俗称”的协议,并不具备法律效力,它体现了互联网人的“契约精神”。行业从业者会自觉遵守该协议,因此它又被称为“君子协议”。
聚焦网络爬虫:是面向特定需求的一种网络爬虫程序。它与通用爬虫的区别在于,聚焦爬虫在实施网页抓取的时候会对网页内容进行筛选和处理,尽量保证只抓取与需求相关的网页信息
。聚焦网络爬虫极大地节省了硬件和网络资源,由于保存的页面数量少所以更新速度很快,这也很好地满足一些特定人群对特定领域信息
的需求。
增量式网络爬虫:是指对已下载网页采取增量式更新,它是一种只爬取新产生的或者已经发生变化网页的爬虫程序,能够在一定程度上保证所爬取的页面是最新的页面
应用
1) 数据分析
在数据分析领域,网络爬虫通常是搜集海量数据的必备工具。对于数据分析师而言,要进行数据分析,首先要有数据源,而学习爬虫,就可以获取更多的数据源。在采集过程中,数据分析师可以按照自己目的去采集更有价值的数据,而过滤掉那些无效的数据。
2) 商业领域
对于企业而言,及时地获取市场动态、产品信息至关重要。企业可以通过第三方平台购买数据,比如贵阳大数据交易所、数据堂等,当然如果贵公司有一个爬虫工程师的话,就可通过爬虫的方式取得想要的信息。
2. 第一个爬虫demo
使用 Python 内置的urllib 库
获取网页的 html 信息
。注意,urllib 库属于 Python 的标准库模块,无须单独安装,它是 Python 爬虫的常用模块。
爬取百度的HTML 代码
# 导入urllib包
# import urllib.request
# 另外一种导入包的方式
from urllib import request
# 获取百度首页的Html信息
respond = request.urlopen('http://www.baidu.com')
# 输出HTML 信息
# 提取响应内容
# 使用响应回来的数据 然后使用read()方法进行解码
html = respond.read().decode('utf-8')
print(html)
在本节您认识了第一个爬虫库 urllib,下面关于 urllib 做简单总结。
1) urlopen()
表示向网站发起请求并获取响应对象,如下所示:
代码语言:python代码运行次数:0复制urllib.request.urlopen(url,timeout)
urlopen() 有两个参数,说明如下:
- url:表示要
爬取数据的 url 地址
。 - timeout:设置等待超时时间,
指定时间内未得到响应
则抛出超时异常
。
2) Request()
该方法用于创建请求对象、包装请求头,比如重构 User-Agent(即用户代理,指用户使用的浏览器)使程序更像人类的请求,而非机器。重构 User-Agent
是爬虫和反爬虫斗争的第一步。在下一节会做详细介绍。
urllib.request.Request(url,headers)
参数说明如下:
- url:请求的URL地址。
- headers:重构请求头。
3) html响应对象方法
代码语言:python代码运行次数:0复制bytes = response.read() # read()返回结果为 bytes 数据类型
string = response.read().decode() # decode()将字节串转换为 string 类型
url = response.geturl() # 返回响应对象的URL地址
code = response.getcode() # 返回请求时的HTTP响应码
4) 编码解码操作
代码语言:python代码运行次数:0复制#字符串转换为字节码
string.encode("utf-8")
#字节码转换为字符串
bytes.decode("utf-8")
3. User-Agent 用户代理
介绍
User-Agent 即用户代理
,简称“UA”
,它是一个特殊字符串头
。网站服务器通过识别 “UA”来确定用户所使用的操作系统版本、CPU 类型、浏览器版本等信息。而网站服务器则通过判断 UA 来给客户端发送不同的页面。
我们知道,网络爬虫使用程序代码
来 访问网站
,因此爬虫程序也被称为“网络机器人”。
绝大多数网站都具备一定的反爬能力
,禁止网爬虫大量地访问网站
网站通过识别请求头中 User-Agent 信息
来判断是否是爬虫访问网站
。如果是,网站首先对该 IP 进行预警
,对其进行重点监控,当发现该 IP 超过规定时间内的访问次数
, 将在一段时间内禁止其再次访问网站
。
常见的 User-Agent 请求头
系统 | 浏览器 | User-Agent字符串 |
---|---|---|
Mac | Chrome | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36 |
Mac | Firefox | Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:65.0) Gecko/20100101 Firefox/65.0 |
Mac | Safari | Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.3 Safari/605.1.15 |
Windows | Edge | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/18.17763 |
Windows | IE | Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko |
Windows | Chrome | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36 |
iOS | Chrome | Mozilla/5.0 (iPhone; CPU iPhone OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/31.0.1650.18 Mobile/11B554a Safari/8536.25 |
iOS | Safari | Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4 |
Android | Chrome | Mozilla/5.0 (Linux; Android 4.2.1; M040 Build/JOP40D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36 |
Android | Webkit | Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; M351 Build/KTU84P) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 |
使用上表中的浏览器 UA,我们可以很方便的构建出 User-Agent。通过在线识别工具,可以查看本机的浏览器版本以及 UA 信息
查看爬虫程序的UA信息
下面,通过向 HTTP 测试网站(http://httpbin.org/)发送 GET 请求来查看请求头信息,从而获取爬虫程序的 UA
代码语言:python代码运行次数:0复制from urllib import request
# 定义变量:URL 与 headers
url = 'http://httpbin.org/get' #向测试网站发送请求
#重构请求头,伪装成 Mac火狐浏览器访问,可以使用上表中任意浏览器的UA信息
headers = {
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:65.0) Gecko/20100101 Firefox/65.0'}
# 1、创建请求对象,包装ua信息
req = request.Request(url=url,headers=headers)
# 2、发送请求,获取响应对象
res = request.urlopen(req)
# 3、提取响应内容
html = res.read().decode('utf-8')
print(html)
响应结果为:
代码语言:python代码运行次数:0复制{
"args": {},
"headers": {
"Accept-Encoding": "identity",
"Host": "httpbin.org",
#伪装成了Mac火狐浏览器
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:65.0) Gecko/20100101 Firefox/65.0",
"X-Amzn-Trace-Id": "Root=1-6034a52f-372ca79027da685c3712e5f6"
},
"origin": "121.17.25.194",
"url": "http://httpbin.org/get"
}
上述代码重构了 User-Agent 字符串信息.
这样就解决了网站通过识别 User-Agent 来封杀爬虫程序的问题
。当然这只是应对反爬策略的第一步。重构 UA 也可以通过其他模块实现,比如 requests 模块,这在后续内容会做相应介绍。
4. 构建User-Agnet代理池
自定义UA代理池
构建代理池的方法也非常简单,在您的 Pycharm 工作目录中定义一个 ua_info.py 文件,并将以下 UA 信息以列表的形式粘贴到该文件中,如下所示:
代码语言:python代码运行次数:0复制ua_list = [
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
'User-Agent:Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11',
'Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)',
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50',
'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0',
' Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1',
' Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1',
]
经过上述操作,用户代理池就构建成功。
模块随机获取UA
您也可以使用专门第三方的模块来随机获取浏览器 UA 信息,不过该模块需要单独安装,安装方式如下:
pip install fake-useragent
下载安装成功后,演示如下代码:
代码语言:python代码运行次数:0复制from fake_useragent import UserAgent#实例化一个对象
ua=UserAgent()
print(ua.ie) #随机获取一个ie浏览器ua
print(ua.firefox) #随机获取一个火狐浏览器ua
输出结果:
代码语言:python代码运行次数:0复制#随机获取ie的ua信息
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/4.0; GTB7.4; InfoPath.3; SV1; .NET CLR 3.1.76908; WOW64; en-US)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0
#随机获取火狐的ua信息
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:21.0) Gecko/20100101 Firefox/21.0
Mozilla/5.0 (Windows NT 5.0; rv:21.0) Gecko/20100101 Firefox/21.0
5. Python实现编码与解码
Python 的标准库urllib.parse
模块中提供了用来编码和解码的方法,分别是 urlencode() 与 unquote() 方法。
方法 | 说明 |
---|---|
urlencode() | 该方法实现了对 url 地址的 |
unquote() | 该方法将编码后的 url 地址 |
1) 编码urlencode()
下面以百度搜索为例进行讲解。首先打开百度首页,在搜索框中输入“爬虫”,然后点击“百度一下”。当搜索结果显示后,此时地址栏的 URL 信息,如下所示:
https://www.baidu.com/s?wd=爬虫&rsv_spt=1&rsv_iqid=0xa3ca348c0001a2ab&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ib&rsv_sug3=8&rsv_sug1=7&rsv_sug7=101
可以看出 URL 中有很多的查询字符串,而第一个查询字符串就是“wd=爬虫”,而“爬虫”则代表您输入的值。
在网页地址栏中删除多余的查询字符串,最后显示的 URL 如下所示:
https://www.baidu.com/s?wd=爬虫
使用搜索修改后的 URL 进行搜索,依然会得到相同页面
。因此可知“wd”参数是百度搜索的关键查询参数。下面编写爬虫程序对 “wd=爬虫”进行编码,如下所示:
#导入parse模块
from urllib import parse
#构建查询字符串字典
query_string = {'wd' : '爬虫'}
#调用parse模块的urlencode()进行编码
result = parse.urlencode(query_string)
#使用format函数格式化字符串,拼接url地址
url = 'http://www.baidu.com/s?{}'.format(result)print(url)
输出结果,如下所示:
代码语言:python代码运行次数:0复制wd=爬虫
http://www.baidu.com/s?wd=爬虫
编码后的 URL 地址依然可以通过地网页址栏实现搜索功能。
除了使用 urlencode() 方法之外,也可以使用quote(string) 方法实现编码
,代码如下:
from urllib import parse
#注意url的书写格式,和 urlencode存在不同
url = 'http://www.baidu.com/s?wd={}'
word = input('请输入要搜索的内容:')
#quote()只能对字符串进行编码
query_string = parse.quote(word)print(url.format(query_string))
输出结果如下:
代码语言:python代码运行次数:0复制输入:请输入要搜索的内容:编程帮www.biancheng.net
输出:http://www.baidu.com/s?wd=编程帮www.biancheng.net
注意:quote() 只能对字符串编码,而 urlencode() 可以直接对查询字符串字典进行编码。因此在定义 URL 时,需要注意两者之间的差异。方法如下:
代码语言:python代码运行次数:0复制# urllib.parseurllib.parse.urlencode({'key':'value'}) #字典urllib.parse.quote(string) #字符串
2) 解码unquote(string)
解码是对编码后的 URL 进行还原的一种操作,示例代码如下:
代码语言:python代码运行次数:0复制from urllib import parsestring = '爬虫'result = parse.unquote(string)print(result)
输出结果:
爬虫
3) URL地址拼接方式
最后,给大家介绍三种拼接 URL 地址的方法。除了使用 format() 函数外,还可以使用字符串相加,以及字符串占位符,总结如下:
代码语言:python代码运行次数:0复制# 1、字符串相加
baseurl = 'http://www.baidu.com/s?'
params='wd=爬虫'
url = baseurl params
# 2、字符串格式化(占位符)
params='wd=爬虫'
url = 'http://www.baidu.com/s?%s'% params
# 3、format()方法
url = 'http://www.baidu.com/s?{}'
params='wd=爬虫'
url = url.format(params)