Python简单爬虫第四蛋!

第四讲:

  今天我们来讲一下上期遗漏的问题,首先是讲述了基于bs4库的HTML内容查找的方法。

  主要的一个方法是:

  <>.find_all(name,attrs,recursive,string,**kwargs)

  返回的是一个列表对象,存储的是查找的结果,

  Name参数是对标签名的检索字符串

  例如:

1  for link in soup.find_all('a'):
2 
3           print(link.get('href'))

  就是第三讲中的最后一个例子,soup.find_all(‘a’)

  返回一个全HTML文档的所有的<a>标签的一个列表,然后通过for循环一一读取,最后输出所有的url连接,就这么简单。

  Attrs参数是对标签属性值的检索字符串

  Recursive是否都子孙全部检索,默认为True

  String <>…</>中字符串区域的检索字符串

  下面用Ipython来演示:

  首先是name参数,返回的是所有<a>标签组成的一个列表。

  接着是attrs参数,返回有atitle属性值的标签

  剩下的就不一一详细介绍了,下面介绍两个等价:

  <tag>(…) 等价于 <tag>.find_all(…)

  soup(…) 等价于 soup.find_all(…)

  还有一个方法是<>.find() 搜索且返回一个结果,同.find_all()参数。

  下面我们进行一个实战练习,准备好IDE环境,一起来做吧。

 

  这是票房网的一个数据,现在显示的是《后来的我们》票房最高,啧啧啧,我也想去看啊~~

  哎,跑题了,我们的目标是把这个网页的数据给爬下来,然后绘制成我们自己写的一个二位表格。

  主要是分为三步走:

  ①   获取票房排名的网页内容

  ②   提取网页内容中的信息到适合的数据结构

  ③   利用数据结构展示并输出结果

  为此我们编写了三个函数。

  第一个,当然是我们的通用代码框架了。

 

 1 '''通用代码框架'''
 2 
 3 import requests
 4 
 5  
 6 
 7 def getHTML_Text(url):
 8 
 9     try:
10 
11         r = requests.get(url,timeout = 20)
12 
13         r.raise_for_status() #如果状态不是200,则产生异常
14 
15         r.encoding = r.apparent_encoding
16 
17         return r.text
18 
19     except:
20 
21         return '产生异常'

 

  上述函数返回的是网页的内容,然后第二个是提取有用信息到我们的数据结构里面去。

 

 

  首先我们从浏览器里面用审查元素功能,找到我们所需数据的位置,可以看到我们需要的信息都在<tr >的这个标签和他的子孙节点标签里面。

  做一个数据结构,只要把采集到的数据放进里面就ok了。

电影名称name

票房

Total_num

人次

People

场次

Play_num

更新时间

Update_time

 

  直接看第二个函数:

 1 import bs4
 2 
 3 from bs4 import BeautifulSoup
 4 
 5 def fillList(ulist,html):
 6 
 7     soup = BeautifulSoup(html,'html.parser')
 8 
 9     for tr in soup.find('tbody').children:
10 
11         if isinstance(tr,bs4.element.Tag):
12 
13             tds = tr('td')
14 
15             ulist.append([tds[0]('a')[0].string,tds[1].string,
16 
17                           tds[2].string,tds[3].string,tds[4].string])
18 
19  

  该函数有两个参数,第一个ulist是一个存储结果的列表对象,

  第二个参数是html文本,就是我们第一个函数爬取得到的内容,然后我们用BeautifulSoup对其进行解析提取我们需要的信息。

  然后通过一个.children产生的迭代器对象,对找到的<tr>标签的子孙节点进行一个迭代提取信息。看下图:

   

  我们可以简单分析到:<tr>标签下面的都是<td>的子标签,而这些子标签的内容就是我们需要的信息,就可以用.string属性了。只是第一个<td>标签里面还有一个<a>标签,所以我们需要先查找到他的<a>标签,然后再用.string属性来提取信息。(tds[0]('a')[0].string)

  最后看第三个函数:

 1 def print_all_result(ulist):
 2 
 3     print("{:16}\t{:8}\t{:8}\t{:8}\t{:20}"
 4 
 5           .format('电影名称','票房','人次','场次','更新时间',chr(12288)))
 6 
 7     for i in range(len(ulist)):
 8 
 9         u = ulist[i]
10 
11         print("{:16}\t{:8}\t{:8}\t{:8}\t{:20}"
12 
13           .format(u[0],u[1],u[2],u[3],u[4],chr(12288)))

  首先是设计一个表头,然后对存储了结果的列表对象进行迭代,就能打印出我们爬取到的信息了。

 

  最后写一下main()函数:

 1 def main():
 2 
 3     url = 'http://58921.com/daily'
 4 
 5     html = getHTML_Text(url)
 6 
 7     result = []
 8 
 9     fillList(result,html)
10 
11 print_all_result(result)

  大功告成!让我们来看看结果吧!

 

      结果已经成功打印出来了,只是排版还有点小毛病,这个大家回去自己试着排版了,这里就不展示怎么排版了,毕竟这不是主要内容。

我们的重点是怎么分析我们要提取的信息,和怎么设计我们的数据结构,最后是编码,把我们的想法加以实现。

       好了,本期到此结束,下期见。

本期全部代码:

 1 import requests
 2 import bs4
 3 from bs4 import BeautifulSoup
 4 
 5 def getHTML_Text(url):
 6     try:
 7         kv = {'User-Agent':'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'}
 8         r = requests.get(url,timeout = 20,headers = kv)
 9         r.raise_for_status() #如果状态不是200,则产生异常
10         r.encoding = r.apparent_encoding
11         return r.text
12     except:
13         return '产生异常'
14 
15 def fillList(ulist,html):
16     soup = BeautifulSoup(html,'html.parser')
17     for tr in soup.find('tbody').children:
18         if isinstance(tr,bs4.element.Tag):
19             tds = tr('td')
20             ulist.append([tds[0]('a')[0].string,tds[1].string,
21                           tds[2].string,tds[3].string,tds[4].string])
22     
23 def print_all_result(ulist):
24     print("{:16}\t{:8}\t{:8}\t{:8}\t{:20}"
25           .format('电影名称','票房','人次','场次','更新时间',chr(12288)))
26     for i in range(len(ulist)):
27         u = ulist[i]
28         print("{:16}\t{:8}\t{:8}\t{:8}\t{:20}"
29           .format(u[0],u[1],u[2],u[3],u[4],chr(12288)))
30      
31 def main():
32     url = 'http://58921.com/daily'
33     html = getHTML_Text(url)
34     result = []
35     fillList(result,html)
36     print_all_result(result)
37         
38 if __name__ == '__main__':
39     main()

  下期预告:re模块的使用

猜你喜欢

转载自www.cnblogs.com/shuaiqi-XCJ/p/9010497.html