⼀、为什么使⽤Python进⾏⽹络爬⾍?
由于Python语⾔⼗分简洁,使⽤起来⼜⾮常简单、易学,通过Python 进⾏编写就像使⽤英语进⾏写作⼀样。另外Python 在使⽤中⼗分⽅便,并不需要IDE,⽽仅仅通过sublime text 就能够对⼤部分的中⼩应⽤进⾏开发;除此之外Python 爬⾍的框架功能⼗分强⼤,它的框架能够对⽹络数据进⾏爬取,还能对结构性的数据进⾏提取,经常⽤在数据的挖掘、历史数据的存储和信息的处理等程序内;Python⽹络的⽀持库和html的解析器功能⼗分强⼤,借助⽹络的⽀持库通过较少代码的编写,就能够进⾏⽹页的下载,且通过⽹页的解析库就能够对⽹页内各标签进⾏解析,和正则的表达式进⾏结合,⼗分便于进⾏⽹页内容的抓取。所以Python在⽹络爬⾍⽹⾯有很⼤的优势。
⼆、判断⽹站数据是否⽀持爬取
⼏乎每个⽹站都有⼀个名为 robots.txt 的⽂档,当然也有部分⽹站没有设定robots.txt。如果⽹站没有设定 robots.txt 就可以通过⽹络爬⾍获取没有⼝令加密的数据,也就是这个⽹站所有页⾯数据都可以爬取。当然如果⽹站有 robots.txt ⽂档,就要判断是否有禁⽌访客获取的数据。
上图淘宝⽹的robots.txt⽂件内容
淘宝⽹允许部分爬⾍访问它的部分路径,⽽对于没有得到允许的⽤户,则全部禁⽌爬取,代码如下:
User-Agent:*Disallow:/12
这⼀句代码的意思是除前⾯指定的爬⾍外,不允许其他爬⾍爬取任何数据。
三、requests 库抓取⽹站数据
1.如何安装 requests 库
1.⾸先在 PyCharm 中安装 requests 库2.打开 PyCharm,单击“File”(⽂件)菜单3.选择“Setting for New Projects…”命令
4.选择“Project Interpreter”(项⽬编译器)命令5.确认当前选择的编译器,然后单击右上⾓的加号。
6.在搜索框输⼊:requests(注意,⼀定要输⼊完整,不然容易出错),然后单击左下⾓的“Install Package”(安装库)按钮。
安装完成后,会在 Install Package 上显⽰“Package‘requests' installed successfully”(库的请求已成功安装),如果安装不成功将会显⽰提⽰信息。
四、爬⾍的基本原理
⽹页请求的过程分为两个环节:
1. Request (请求):每⼀个展⽰在⽤户⾯前的⽹页都必须经过这⼀步,也就是向服务器发送访问请求。
2. Response(响应):服务器在接收到⽤户的请求后,会验证请求的有效性,然后向⽤户(客户端)发送响应的内容,客户端接收服务器响应的内容,将内容展⽰出来,就是我们所熟悉的⽹页请求
⽹页请求的⽅式也分为两种:
1. GET:最常见的⽅式,⼀般⽤于获取或者查询资源信息,也是⼤多数⽹站使⽤的⽅式,响应速度快。2. POST:相⽐ GET ⽅式,多了以表单形式上传参数的功能,因此除查询信息外,还可以修改信息。所以,在写爬⾍前要先确定向谁发送请求,⽤什么⽅式发送。
五、使⽤ GET ⽅式抓取数据
复制任意⼀条⾸页⾸条新闻的标题,在源码页⾯按【Ctrl+F】组合键调出搜索框,将标题粘贴在搜索框中,然后按【Enter】键。标题可以在源码中搜索到,请求对象是www.cntour.cn,请求⽅式是GET(所有在源码中的数据请求⽅式都是GET),如图 9所⽰。
确定好请求对象和⽅式后,在 PyCharm 中输⼊以下代码:
import requests #导⼊requests包url = 'http://www.cntour.cn/'
strhtml = requests.get(url) #Get⽅式获取⽹页数据
print(strhtml.text)1234
加载库使⽤的语句是 import+库的名字。在上述过程中,加载 requests 库的语句是:import requests。
⽤ GET ⽅式获取数据需要调⽤ requests 库中的 get ⽅法,使⽤⽅法是在 requests 后输⼊英⽂点号,如下所⽰:
requests.get1
将获取到的数据存到 strhtml 变量中,代码如下:
strhtml = request.get(url)1
这个时候 strhtml 是⼀个 URL 对象,它代表整个⽹页,但此时只需要⽹页中的源码,下⾯的语句表⽰⽹页源码:
strhtml.text1
六、使⽤ POST ⽅式抓取数据
按快捷键 F12,进⼊开发者模式,单击 Network,此时内容为空,如图所⽰:
在有道翻译中输⼊“我爱中国”,单击“翻译”按钮
在开发者模式中,依次单击“Network”按钮和“XHR”按钮,找到翻译数据
单击 Headers,发现请求数据的⽅式为 POST。
找到数据所在之处并且明确请求⽅式之后,接下来开始撰写爬⾍。⾸先,将 Headers 中的 URL 复制出来,并赋值给 url,代码如下:
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'1
POST 的请求获取数据的⽅式不同于 GET,POST 请求数据必须构建请求头才可以。Form Data 中的请求参数如图
将其复制并构建⼀个新字典:
From_data={'i':'我愛中國','from':'zh-CHS','to':'en','smartresult':'dict','client':'fanyideskweb','salt':'15477056211258','sign':'b3589f32c38bc9e3876a570b8a992604','ts':'1547705621125','bv':'b33a2f3f9d09bde064c9275bcb33d94e','doctype':'json','version':'2.1','keyfrom':'fany1
将字符串格式的数据转换成 JSON 格式数据,并根据数据结构,提取数据,并将翻译结果打印出来,代码如下:
import json
content = json.loads(response.text)
print(content['translateResult'][0][0]['tgt'])123
使⽤ requests.post ⽅法抓取有道翻译结果的完整代码如下:
import requests #导⼊requests包import json
def get_translate_date(word=None):
url = 'http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
From_data={'i':word,'from':'zh-CHS','to':'en','smartresult':'dict','client':'fanyideskweb','salt':'15477056211258','sign':'b3589f32c38bc9e3876a570b8a992604','ts':'1547705621125','bv':'b33a2f3f9d09bde064c9275bcb33d94e','doctype':'json','version':'2.1','keyfrom':'fanyi.we #请求表单数据
response = requests.post(url,data=From_data) #将Json格式字符串转字典
content = json.loads(response.text) print(content)
#打印翻译后的数据
#print(content['translateResult'][0][0]['tgt'])if __name__=='__main__':
get_translate_date('我爱中国')1234567891011121314
七、使⽤ Beautiful Soup 解析⽹页
通过 requests 库已经可以抓到⽹页源码,接下来要从源码中找到并提取数据。Beautiful Soup 是 python 的⼀个库,其最主要的功能是从⽹页中抓取数据。Beautiful Soup ⽬前已经被移植到 bs4 库中,也就是说在导⼊ Beautiful Soup 时需要先安装 bs4 库。安装 bs4 库的⽅式如图 所⽰:
安装好 bs4 库以后,还需安装 lxml 库。如果我们不安装 lxml 库,就会使⽤ Python 默认的解析器。尽管 Beautiful Soup 既⽀持 Python 标准库中的 HTML 解析器⼜⽀持⼀些第三⽅解析器,但是 lxml 库具有功能更加强⼤、速度更快的特点,因此笔者推荐安装 lxml 库。
安装 Python 第三⽅库后,输⼊下⾯的代码,即可开启 Beautiful Soup 之旅:
import requests #导⼊requests包from bs4 import BeautifulSoupurl='http://www.cntour.cn/'strhtml=requests.get(url)
soup=BeautifulSoup(strhtml.text,'lxml')
data = soup.select('#main>div>div.mtop.firstMod.clearfix>div.centerBox>ul.newsList>li>a')print(data)1234567
代码运⾏结果如图。
Beautiful Soup 库能够轻松解析⽹页信息,它被集成在 bs4 库中,需要时可以从 bs4 库中调⽤。其表达语句如下:
from bs4 import BeautifulSoup1
⾸先,HTML ⽂档将被转换成 Unicode 编码格式,然后 Beautiful Soup 选择最合适的解析器来解析这段⽂档,此处指定 lxml 解析器进⾏解析。解析后便将复杂的 HTML ⽂档转换成树形结构,并且每个节点都是 Python 对象。这⾥将解析后的⽂档存储到新建的变量 soup 中,代码如下:
soup=BeautifulSoup(strhtml.text,'lxml')1
接下来⽤ select(选择器)定位数据,定位数据时需要使⽤浏览器的开发者模式,将⿏标光标停留在对应的数据位置并右击,然后在快捷菜单中选择“检查”命令
随后在浏览器右侧会弹出开发者界⾯,右侧⾼亮的代码(参见图 19(b))对应着左侧⾼亮的数据⽂本(参见图 19(a))。右击右侧⾼亮数据,在弹出的快捷菜单中选择“Copy”➔“Copy Selector”命令,便可以⾃动复制路径。
将路径粘贴在⽂档中,代码如下:
#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li:nth-child(1) > a1
由于这条路径是选中的第⼀条的路径,⽽我们需要获取所有的头条新闻,因此将 li:nth-child(1)中冒号(包含冒号)后⾯的部分删掉,代码如下:
#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a1
使⽤ soup.select 引⽤这个路径,代码如下:
data = soup.select('#main > div > div.mtop.firstMod.clearfix > div.centerBox > ul.newsList > li > a')1
⼋、清洗和组织数据
⾄此,获得了⼀段⽬标的 HTML 代码,但还没有把数据提取出来,接下来在 PyCharm 中输⼊以下代码:纯⽂本复制
for item in data: result={
'title':item.get_text(), 'link':item.get('href') }
print(result)123456
代码运⾏结果如图 所⽰:
⾸先明确要提取的数据是标题和链接,标题在<a>标签中,提取标签的正⽂⽤ get_text() ⽅法。链接在<a>标签的 href 属性中,提取标签中的 href 属性⽤ get() ⽅法,在括号中指定要提取的属性数据,即 get('href')。
从图 20 中可以发现,⽂章的链接中有⼀个数字 ID。下⾯⽤正则表达式提取这个 ID。需要使⽤的正则符号如下:\\d匹配数字+匹配前⼀个字符1次或多次在 Python 中调⽤正则表达式时使⽤ re 库,这个库不⽤安装,可以直接调⽤。在 PyCharm 中输⼊以下代码:
import re
for item in data: result={
\"title\":item.get_text(), \"link\":item.get('href'),
'ID':re.findall('\\d+',item.get('href')) }
print(result)12345678
运⾏结果如图 所⽰:
这⾥使⽤ re 库的 findall ⽅法,第⼀个参数表⽰正则表达式,第⼆个参数表⽰要提取的⽂本。
九.爬⾍攻防战
爬⾍是模拟⼈的浏览访问⾏为,进⾏数据的批量抓取。当抓取的数据量逐渐增⼤时,会给被访问的服务器造成很⼤的压⼒,甚⾄有可能崩溃。换句话就是说,服务器是不喜欢有⼈抓取⾃⼰的数据的。那么,⽹站⽅⾯就会针对这些爬⾍者,采取⼀些反爬策略。
服务器第⼀种识别爬⾍的⽅式就是通过检查连接的 useragent 来识别到底是浏览器访问,还是代码访问的。如果是代码访问的话,访问量增⼤时,服务器会直接封掉来访 IP。那么应对这种初级的反爬机制,我们应该采取何种举措?
还是以前⾯创建好的爬⾍为例。在进⾏访问时,我们在开发者环境下不仅可以找到 URL、Form Data,还可以在 Request headers 中构造浏览器的请求头,封装⾃⼰。服务器识别浏览器访问的⽅法就是判断 keyword 是否为 Request headers 下的 User-Agent,如图:
因此,我们只需要构造这个请求头的参数。创建请求头部信息即可,代码如下:
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36'}response = request.get(url,headers=headers)12
写到这⾥,很多读者会认为修改 User-Agent 很太简单。确实很简单,但是正常⼈1秒看⼀个图,⽽个爬⾍1秒可以抓取好多张图,⽐如 1 秒抓取上百张图,那么服务器的压⼒必然会增⼤。也就是说,如果在⼀个 IP 下批量访问下载图⽚,这个⾏为不符合正常⼈类的⾏为,肯定要被封 IP。
其原理也很简单,就是统计每个IP的访问频率,该频率超过阈值,就会返回⼀个验证码,如果真的是⽤户访问的话,⽤户就会填写,然后继续访问,如果是代码访问的话,就会被封 IP。这个问题的解决⽅案有两个,第⼀个就是常⽤的增设延时,每 3 秒钟抓取⼀次,代码如下:
import timetime.sleep(3)12
但是,我们写爬⾍的⽬的是为了⾼效批量抓取数据,这⾥设置 3 秒钟抓取⼀次,效率未免太低。其实,还有⼀个更重要的解决办法,那就是从本质上解决问题。
不管如何访问,服务器的⽬的就是查出哪些为代码访问,然后封锁 IP。解决办法:为避免被封 IP,在数据采集时经常会使⽤代理。当然,requests 也有相应的 proxies 属性。到此这篇关于Python爬⾍教程知识点总结的⽂章就介绍到这了,更多相关Python爬⾍教程分享内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
因篇幅问题不能全部显示,请点此查看更多更全内容