第三章,在我的第一个爬虫程序学习了爬虫的原理和网页的结构之后,我们了解到爬虫的任务是两件事:请求网页和解析提取信息。本章从这两个方面入手。首先安装用于请求和解析网页的Python第三方库,然后会教读者写一个简单的爬虫程序。
本章涉及的主要知识点如下。
Python第三方库:学习Python第三方库的概念和安装方法。
请求库:学习使用请求库的原则和方法。
精美汤库:学习使用精美汤库的原理和方法。
Requests和BeautifulSoup库的联合应用:通过本章末尾给出的例子,演示如何使用这两个库进行爬虫的方法和技巧。
3.1 Python第三方库
本节主要介绍Python第三方库的基本概念和安装方法。只有使用第三个库,爬虫才能事半功倍。
3.1.1 Python第三方库的概念
Python之所以强大并逐渐流行,部分原因是由于其强大的第三方库。这样用户就不用去理解底层的思想,用最少的代码写出最多的功能。就像制造自行车一样,你需要:
铁矿石;
橡胶;
扳手之类的工具。
如果不用第三库,就需要从原始资料开始,一步一步的制作。不知道做一个轮子要多久!第三方库的使用是不同的。车轮和车身已经制造完成,拼接后即可使用(有些车可以直接使用)。这种现成的Python第三方库。
3.1.2 Python第三方库的安装方法
由于Python第三方库非常容易使用,本节将介绍如何安装这些方便的第三方库。
图3.1在pycharm中安装第三个库的步骤1
图3.2在pycharm中安装第三个库的步骤2
安装完成后,PyCharm会有一个成功提示。读者还可以通过展开项目解释器选项来查看已安装的库,并单击减号按钮来卸载不必要的库。
2.安装在PIP中
安装Python后,PIP也会同时安装。我们可以输入:
Pip – version如果出现以下提示,则意味着Pip已成功安装。
PIP 9.0.1来自d:\ Anaconda \ lib \ site-packages(Python 3.6)成功安装PIP后,您可以通过在命令行cmd中输入以下代码来下载第三方库:
pip3 install packagename#packagename为安装库的名称,在这里输入pip3 install beautifulsoup4即可下载beautifulsoup4库了。
图3.3下载whl文件
(2)然后在命令行输入:
Pip3安装轮(3)等待执行,成功执行后,进入:
Cd D:\python\ku#后面是下载whl文件的路径(4)最后,输入:
pip 3 install lxml-3 . 7 . 2-CP35-CP35m-win _ amd64 . whl # lxml-3 . 7 . 2-CP35-CP35m-win _ amd64 . whl是您下载的文件的完整路径名,以便您将库下载到本地。通过whl文件,您可以自动安装相关软件包。
图3.5复制请求标题
如何使用请求标题:
import requests headers = { User-Agent ‘:’ Mozilla/5.0(Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML,像壁虎一样)Chrome/53 . 0 . 2785 . 143 Safari/537.36 ‘ } RES = Requests . get(‘ http://bj . xiaozhu . com/’,Headers=headers) #get方法添加请求头print(res.text)请求库不仅包括get()方法,还包括post()方法。post()方法用于向需要登录获取数据的攀登网站提交表单。这部分在后面的章节会学到,这里就不赘述了。学会get()方法就足够我们爬大部分网站了。
请求图书馆的请求不会“一帆风顺”。当遇到某些情况时,请求库会抛出错误或异常。请求库中有四种主要类型的错误和异常。
由于网络问题(如DNS查询失败、连接拒绝等), Requests抛出ConnectionError异常。).
Response.raise _ for _ status()抛出HTTPError异常,因为HTTP请求返回了一个不成功的状态码(如果网页不存在,则返回404错误)。
由于请求超时,Requests引发超时异常。
Requests引发TooManyRedirects异常,因为请求超出了设置的最大重定向数。
所有由请求显式抛出的异常都是从请求中继承的。例外情况。请求异常。当发现这些错误或异常时,爬虫的程序又开始运行,爬取的数据又会被重新爬取,这对爬虫的效率和质量都是不利的。这时可以通过Python中的try来避免异常,具体使用方法如下:
import requests headers = { User-Agent ‘:’ Mozilla/5.0(Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML,像壁虎一样)Chrome/53 . 0 . 2785 . 143 Safari/537.36 ‘ } RES = requests . get(‘ http://bj . xiaozhu . com/’,Headers = Headers)try:print(RES . text)except connection error:#如果出现错误,将执行以下操作。Print(‘连接被拒绝’)将通过try和except,如果请求成功,将打印网页的源代码。如果请求中有ConnectionError异常,会打印“拒绝连接”,这样程序就不会报错,而是给程序员一个提示,不会影响后面代码的运行。
3.2.2 BeautifulSoup库
BeautifulSoup库是一个非常流行的Python模块。通过BeautifulSoup库,可以方便地解析Requests库请求的网页,将网页的源代码解析成一个Soup文档,从而过滤提取数据。
来自bs4的导入请求import beautiful soup headers = { ‘ User-Agent ‘:’ Mozilla/5.0(Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML,like Gecko)Chrome/53 . 0 . 2785 . 143 Safari/537.36 ‘ } RES = Requests . get(‘ http://bj . xiaozhu . com/’,Headers = Headers)Soup = Beautiful Soup(RES . text,’ html . parser ‘)# print(Soup . pretify())的输出结果如图3.6所示,看起来类似于请求所请求的网页的源代码
图3.6解析Soup文档
BeautifulSoup库不仅支持Python标准库中的HTML解析器,还支持一些第三方解析器。例如,表3.1列出了BeautifulSoup库的主要解析器及其相应的优缺点。
表3.1 BeautifulSoup库解析器
Soup.find_all(‘div ‘,” item))# # Find div标记,class = “item” soup.find _ all (‘div ‘,class = ‘ item ‘)soup . Find _ all(‘ div ‘,attrs = {“class”: “item”}。
find()方法类似于find_all()方法,只是find_all()方法返回文档中所有合格的标记,这是一个集合(class’bs4.element.ResultSet ‘),find()方法返回一个标记(class’bs4.element.Tag ‘)。
3.selector()方法
汤.选择器(div.item & gta & gtH1) #括号被Chrome抄袭。这种方法类似于中国>:湖南省>长沙市,从大到小,提取出需要的信息,可以用Chrome复制,如图3.7所示。
图3.7复制selector()方法
(1)将鼠标定位到要提取数据的位置,单击右键,在弹出的快捷菜单中选择“检查”命令。
(2)右键单击网页源代码中选定的元素。
(3)在弹出的快捷菜单中选择复制选择器。这时,你可以得到:
# page _ list & gtul & gt李:第n个孩子(1)& gt;div . result _ btm _ con . lodgeunitname & gt;span.result _ price & gt我可以通过代码得到房价:Import Requests from BS4 Import Beautiful Soup # Import对应的库文件头= { ‘ user-agent ‘:’ Mozilla/5.0(Windows NT 6.1;Wow 64) apple WebKit/537.36 (khtml,像壁虎一样)chrome/53 . 0 . 2785 . 143 safari/537.36 ‘ } # Request header RES = requests . get(‘ http://bj . xiaozhu . com/’,Headers = Headers)# Request page soup = beautiful soup(RES . text,’ html . parser ‘)# Parse data price = soup . select(‘ # page _ list > ul & gt;李:n-of-type(1)>div . result _ btm _ con . lodgeunitname & gt;span.result _ price & gtI’) #定位元素位置并通过选择器方法提取print(price ),结果将打印在屏幕上[
图3.8提取多个元素
图3.9提取标签文本
此时程序已经在一个页面中爬取了所有的房价信息,但是网站有多个页面,需要构造一个URL列表。详细方法见本章综合示例。
3.2.3 Lxml库
Lxml库是一个基于libxm12的Python包,libxm 12是一个xml解析库。模块用C语言编写,解析速度比BeautifulSoup快。具体用法将在后面的章节中解释。
3.3 综合案例1——爬取北京地区短租房信息
本节我们将使用第三方库Requests和BeautifulSoup来抓取短租中的短租房源信息。
3.3.1 爬虫思路分析
(1)该板块抓取了短租中13页的短租房源信息。通过手动浏览,以下是前四页的网址:
http://bj . xiaozhu . com/http://bj . xiaozhu . com/Search-duanzufang-p2-0/http://bj . xiaozhu . com/Search-duanzufang-P3-0/http://bj . xiaozhu . com/Search-duanzufang-P4-0/然后把第一页的网址改成http://bj.xiaozhu.com/search-duanzufang-p1-0/,就可以正常浏览了所以只需要把P后面的数字改一下就可以构造一个13页的网址了。
(2)这次爬虫是在详情页,需要先爬取进入详情页的URL链接,再爬取数据。
(3)要爬取的信息包括:标题、地址、价格、楼主姓名、楼主性别以及到楼主头像的链接,如图3.10所示。
图3.10要获取的网页信息
3.3.2 爬虫代码及分析
爬虫代码如下:
01 from bs4 import BeautifulSoup02 import requests03 import time #导入相应的库文件04 05 headers = {06 ‘User-Agent’:’Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.3607 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36’08 } #加入请求头09 10 def judgment_sex(class_name): #定义判断用户性别的函数11 if class_name == [‘member_ico1’]:12 return ‘女’13 else:14 return ‘男’15 16 def get_links(url): #定义获取详细页URL的函数17 wb_data = requests.get(url,headers=headers)18 soup = BeautifulSoup(wb_data.text,’lxml’)19 links = soup.select(‘#page_list > ul > li > a’) #links为URL列表20 for link in links:21 href = link.get(“href”)22 get_info(href) #循环出的URL,依次调用get_info()函数23 24 def get_info(url): #定义获取网页信息的函数25 wb_data = requests.get(url,headers=headers)26 soup = BeautifulSoup(wb_data.text,’lxml’)27 tittles = soup.select(‘div.pho_info > h4’)28 addresses = soup.select(‘span.pr5’)29 prices = soup.select(‘#pricePart > div.day_l > span’)30 imgs = soup.select(‘#floatRightBox > div.js_box.clearfix > div.member_ pic > a > img’)31 names = soup.select(‘#floatRightBox > div.js_box.clearfix > div.w_ 240 > h6 > a’)32 sexs = soup.select(‘#floatRightBox > div.js_box.clearfix > div.member_ pic > div’)33 for tittle, address, price, img, name, sex in zip(tittles,addresses, prices,imgs,names,sexs):34 data = {35 ‘tittle’:tittle.get_text().strip(),36 ‘address’:address.get_text().strip(),37 ‘price’:price.get_text(),38 ‘img’:img.get(“src”),39 ‘name’:name.get_text(),40 ‘sex’:judgment_sex(sex.get(“class”))41 }42 print(data) #获取信息并通过字典的信息打印43 44 if __name__ == ‘__main__’: #为程序的主入口45 urls = [‘http://bj.xiaozhu.com/search-duanzufang-p{}-0/’.format (number) for number in46 range(1,14)] #构造多页URL47 for single_url in urls:48 get_links(single_url) #循环调用get_links()函数49 time.sleep(2) #睡眠2秒
程序运行的部分结果如图3.11所示。01从bs4导入美汤02导入请求03导入时间#导入对应的库文件04 05 headers = { 06 ‘ user-agent ‘:’ Mozilla/5.0(Windows NT 6.1;wow 64)apple WebKit/537.3607(KHTML,像壁虎一样)chrome/53 . 0 . 2785 . 143 safari/537.36 ‘ 08 } #添加请求头09 10 def judgment _ sex(class _ name):#定义判断用户性别的函数11 if class _ name = =[‘ member _ ico 1 ‘]。:12返回’女性’ 13 else:14返回’男性’ 15 16 def get_links(url): #定义获取详情页url的函数17 wb_data = requests.get(url,headers = headers)18 soup = beautiful soup(WB _ data . text,’ lxml ‘)19 links = soup . select(‘ # page _ list & gt;ul & gt李& gta’)# links是由URL列表20为links中的link循环的URL:21 href = link . get(” href “)22 get _ info(href)#。依次调用get_info()函数23 24 def get _ info(URL):#定义获取网页信息的函数25 WB _ data = requests.get (URL,headers = headers)26 soup = beautiful soup(WB _ data . text,’ lxml’) 27 titles = soup.select(。h4′)28地址= soup.select(‘span.pr5’)29价格= soup . select(‘ # price part & gt;div.day _ l & gtspan ‘)30 imgs = soup . select(‘ # float right box & gt;div . js _ box . clear fix & gt;div.member _ pic & gta & gtimg ‘)31 names = soup . select(‘ # float right box & gt;div . js _ box . clear fix & gt;div.w _ 240 & gth6 & gta’)32 sexs = soup . select(‘ # float right box & gt;div . js _ box . clear fix & gt;div.member _ pic & gtdiv’)33 for tittle,address,price,img,name,sex in zip(tittles,addresses,prices,img,names,sexs):34 data = { 35 ‘ tittle ‘:tittle . get _ text()。strip(),36 ‘address’:address.get_text()。strip(),37 ‘price’:price.get_text(),38 ‘img’:img.get(“src “),39 ‘name’:name.get_text(),40′ sex’: judge _ sex (sex。get (“class”)) 41} 42 print (data) #获取信息并打印43 44 if _ _ name _ =’ _ _ main _’: #是程序的主入口45 URLs = [‘http:/。Search-duanzufang-p {}-0/’。format(number)for number in 46 range(1,14)] #构造多页URL 47 for single _ URL in URLs:48 get_links(single _ URL)#调用get _ links()函数49 time.sleep(2) #
图3.11程序运行结果
代码分析:
(1)第1-3行导入程序所需的库,Requests库用于请求一个网页以获取网页数据。BeautifulSoup用于解析web数据。时间库的sleep()方法可以让程序暂停。
(2)第5-8行通过Chrome浏览器的开发者工具复制User-Agent,用来伪装成浏览器,方便爬虫的稳定。
(3)第16-22行定义了get_links()函数,用于获取详细页面的链接。
URL传入后,会被请求和解析。通过Chrome浏览器的“检查”和“复制选择器”,可以找到进入详情页的URL链接,但是URL链接并没有嵌套在标签中,而是在标签的属性信息中,如图3.12所示。
图3.12 URL链接位置
前面提到,可以用get_text()方法获取标签中的文本信息,但是标签中的属性信息需要用get(‘attr ‘)方法获取,如图3.12所示,在href中链接URL,然后用get(‘href ‘)获取网页的URL。
最后调用get_info()函数,传入的参数是获取的网页详情页的链接。
(4)第24-42行定义get_info()函数,用于获取网页信息并输出。
URL传入后,会被请求和解析。通过Chrome浏览器的“检查”和“复制选择器”可以获得相应的信息。因为信息数据是一个列表数据结构,字典数据结构可以通过多次循环来构造,然后输出和打印。
图3.13房东的性别判断
在图中所示的区域,您可以发现女房东的信息是
(6)在程序主入口第44行到第49行,利用链表的演绎公式构造了13个URL,依次调用get_links()函数。time.sleep(2)意思是每个周期暂停程序2秒,防止爬虫因为网页频繁请求而失败。
3.4 综合案例2——爬取酷狗TOP500的数据
本节将使用第三方库Requests和BeautifulSoup抓取酷狗网榜单中酷狗TOP500的信息。
3.4.1 爬虫思路分析
(1)本节爬取的内容是酷狗榜单中酷狗TOP500的音乐信息,如图3.14所示。
图3.14酷狗TOP500界面
(2)网页版酷狗无法手动翻页进行下一次浏览,而是通过观察第一页的网址:
这里的Http://www.kugou.com/yy/rank/home/1-8888.html试图将数字1改为数字2,然后浏览,并返回第2页上的信息(如图3.15所示)。经过多次尝试,我发现换不同的号码意味着不同的页面,所以我只需要在home/之后换号码就可以了。由于每页显示22首歌曲,因此总共需要23个URL。
图3.15第2页URL
(3)要爬取的信息包括排名、歌手、歌名、歌曲时间,如图3.16所示。
图3.16要获取的网页信息
3.4.2 爬虫代码及分析
爬虫代码如下:
01导入请求02从bs4导入美汤03导入时间#导入对应的库文件04 05 headers = { 06 ‘ user-agent ‘:’ Mozilla/5.0(Windows NT 6.1;wow 64)apple WebKit/537.3607(KHTML,像壁虎一样)Chrome/56 . 0 . 2924 . 87 Safari/537.36 ‘ 08 } #添加请求头09 10 def get_info(url): #定义函数11 wb_data = requests.get(url,headers = headers)12 soup = beautiful soup(WB _ data . text,’ lxml ‘)13 ranks = soup . select(‘ span . PC _ temp _ num ‘)12ul & gt李& gta’)15次= soup . select(‘ span . PC _ temp _ tips _ r & gt;span’)16 for rank,title,time in zip(ranks,titles,times):17 data = { 18 ‘ rank ‘:rank . get _ text()。strip(),19 ‘singer’:title.get_text()。split(‘-‘)[0],20 ‘song’:title.get_text()。split(‘-‘)[0],#通过split 21’ time ‘获取歌手和歌曲信息:time。get _ text()。Strip () 22} 23 print (data)获取爬虫的信息并以字典格式打印24 25 if _ _ name _ =’ _ _ main _’: #程序主入口26 URLs =[‘ http://Www.kugou.com/yy/rank/home/{}-8888.html’.format(str(I))for ii in 27 range(1,24)] #构造多页URL 28 for URL in URLs:29 get_info(URL)#调用Get _ info()函数time.sleep(1) #程序运行的部分结果如图3.17所示。
代码分析:
(1)第1-3行导入程序需要的库,其中Requests库用于请求网页获取网页数据,BeautifulSoup用于解析网页数据,time库的sleep()方法可以让程序暂停。
(2)第5-8行通过Chrome浏览器的开发者工具复制User-Agent,用来伪装成浏览器,方便爬虫的稳定。
(3)第10-23行定义get_info()函数,用于获取网页信息并输出。
URL传入后,会被请求和解析。通过Chrome浏览器的“检查”和“复制选择器”可以获得相应的信息。因为信息数据是一个列表数据结构,字典数据结构可以通过多次循环来构造,然后输出和打印。
图3.17程序运行结果
注意:本案例并未完全使用“Copy selector”的全部信息,由于有些标签是固定的,因此选用部分路径即可。注意:在这种情况下,并没有使用“复制选择器”的所有信息。因为有些标签是固定的,所以可以使用部分路径。
(4)第25 ~ 29行为程序的主入口。通过观察网页的URL,利用列表的派生构造23个URL,依次调用get_info()函数。time.sleep(1)是指每次暂停程序1秒,防止爬虫因为频繁请求网页而失败。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。