爬虫解析提取数据的四种技巧

代码如下:


  1. # -*- coding: UTF-8 -*-  
  2. """  
  3. @Author  :叶庭云  
  4. @公众号  :修炼Python  
  5. @CSDN    :https://yetingyun.blog.csdn.net/  
  6. """  
  7. import requests  
  8. from bs4 import BeautifulSoup  
  9. import openpyxl  
  10. from fake_useragent import UserAgent  
  11. import logging  
  12. # 日志输出的基本配置  
  13. logging.basicConfig(level=logging.INFO, format='%(asctime)s – %(levelname)s: %(message)s' 
  14. # 随机产生请求头  
  15. ua = UserAgent(verify_ssl=Falsepath='fake_useragent.json' 
  16. wb = openpyxl.Workbook()    # 创建工作簿对象  
  17. sheet = wb.active           # 获取工作簿的活动表  
  18. sheet.title = "movie"       # 工作簿重命名  
  19. sheet.append(["排名", "电影名", "导演和主演", "上映时间", "上映地区", "电影类型", "评分", "评价人数", "引言"])  
  20. def random_ua():  
  21.     headers = {  
  22.         "Accept-Encoding": "gzip",  
  23.         "Connection": "keep-alive",  
  24.         "User-Agent": ua.random  
  25.     }  
  26.     return headers  
  27. def scrape_html(url):  
  28.     resp = requests.get(url, headers=random_ua())  
  29.     # print(resp.status_code, type(resp.status_code))  
  30.     if resp.status_code == 200:  
  31.         return resp.text  
  32.     else: 
  33.          logging.info('请求网页失败')  
  34. def get_data(page):  
  35.     global rank  
  36.     url = f"https://movie.douban.com/top250?start={25 * page}&filter="  
  37.     html_text = scrape_html(url)  
  38.     soup = BeautifulSoup(html_text, 'html.parser')  
  39.     lis = soup.find_all('div', class_='item' 
  40.     for li in lis:  
  41.         name = li.find('div', class_='hd').a.span.text  
  42.         temp = li.find('div', class_='bd').p.text.strip().split(' ')  
  43.         director_actor = temp[0]  
  44.         temptemp1 = temp[1].rsplit('/', 2)  
  45.         time_, area, genres = [item.strip() for item in temp1]  
  46.         quote = li.find('p', class_='quote' 
  47.         # 有些电影信息没有一句话引言  
  48.         if quote:  
  49.             quotequote = quote.span.text  
  50.         else:  
  51.             quote = None  
  52.         rating_score = li.find('span', class_='rating_num').text  
  53.         rating_num = li.find('div', class_='star').find_all('span')[-1].text  
  54.         sheet.append([rank, name, director_actor, time_, area, genres, rating_score, rating_num, quote])  
  55.         logging.info([rank, name, director_actor, time_, area, genres, rating_score, rating_num, quote])  
  56.         rank += 1 
  57. if __name__ == '__main__':  
  58.     rank = 1  
  59.     for i in range(10):  
  60.         get_data(i)  
  61.     wb.save(filename='movie_info4.xlsx'

PyQuery

  •  每个网页,都有一定的特殊结构和层级关系,并且很多节点都有 id 或 class 作为区分,我们可以借助它们的结构和属性来提取信息。
  •  强大的 HTML 解析库:pyquery,利用它,我们可以直接解析 DOM 节点的结构,并通过 DOM 节点的一些属性快速进行内容提取。

如下示例:在解析 HTML 文本的时候,首先需要将其初始化为一个 pyquery 对象。它的初始化方式有多种,比如直接传入字符串、传入 URL、传入文件名等等。


  1. from pyquery import PyQuery as pq  
  2. html = '' 
  3. <div>  
  4.     <ul class="clearfix">  
  5.         <li class="item-0">first item</li>  
  6.         <li class="item-1"><a href="link2.html">second item</a></li>  
  7.         <li><img src="http://pic.netbian.com/uploads/allimg/210107/215736-1610027856f6ef.jpg"></li>  
  8.         <li><img src="http://pic.netbian.com//uploads/allimg/190902/152344-1567409024af8c.jpg"></li>   
  9.     </ul>  
  10. </div>  
  11. '''  
  12. doc = pq(html)  
  13. print(doc('li')) 

结果如下:


  1. <li class="item-0">first item</li>  
  2. <li class="item-1"><a href="link2.html">second item</a></li>  
  3. <li><img src="http://pic.netbian.com/uploads/allimg/210107/215736-1610027856f6ef.jpg"/></li>  
  4. <li><img src="http://pic.netbian.com//uploads/allimg/190902/152344-1567409024af8c.jpg"/></li>   

首先引入 pyquery 这个对象,取别名为 pq,然后定义了一个长 HTML 字符串,并将其当作参数传递给 pyquery 类,这样就成功完成了初始化。接下来,将初始化的对象传入 CSS 选择器。在这个实例中,我们传入 li 节点,这样就可以选择所有的 li 节点。

代码如下:


  1. # -*- coding: UTF-8 -*-  
  2. """  
  3. @Author  :叶庭云  
  4. @公众号  :修炼Python  
  5. @CSDN    :https://yetingyun.blog.csdn.net/  
  6. """  
  7. import requests  
  8. from pyquery import PyQuery as pq  
  9. import openpyxl  
  10. from fake_useragent import UserAgent  
  11. import logging  
  12. # 日志输出的基本配置  
  13. logging.basicConfig(level=logging.INFO, format='%(asctime)s – %(levelname)s: %(message)s' 
  14. # 随机产生请求头  
  15. ua = UserAgent(verify_ssl=Falsepath='fake_useragent.json' 
  16. wb = openpyxl.Workbook()    # 创建工作簿对象  
  17. sheet = wb.active           # 获取工作簿的活动表  
  18. sheet.title = "movie"       # 工作簿重命名  
  19. sheet.append(["排名", "电影名", "导演和主演", "上映时间", "上映地区", "电影类型", "评分", "评价人数", "引言"])  
  20. def random_ua():  
  21.     headers = {  
  22.         "Accept-Encoding": "gzip",  
  23.         "Connection": "keep-alive",  
  24.         "User-Agent": ua.random  
  25.     }  
  26.     return headers   
  27. def scrape_html(url):  
  28.     resp = requests.get(url, headers=random_ua())  
  29.     # print(resp.status_code, type(resp.status_code))  
  30.     if resp.status_code == 200:  
  31.         return resp.text 
  32.      else:  
  33.         logging.info('请求网页失败')  
  34. def get_data(page):  
  35.     global rank  
  36.     url = f"https://movie.douban.com/top250?start={25 * page}&filter="  
  37.     html_text = scrape_html(url)  
  38.     doc = pq(html_text)  
  39.     lis = doc('.grid_view li')  
  40.     for li in lis.items():  
  41.         name = li('.hd a span:first-child').text()  
  42.         temp = li('.bd p:first-child').text().split(' ')  
  43.         director_actor = temp[0]  
  44.         temptemp1 = temp[1].rsplit('/', 2)  
  45.         time_, area, genres = [item.strip() for item in temp1]  
  46.         quote = li('.quote span').text()  
  47.         rating_score = li('.star .rating_num').text()  
  48.         rating_num = li('.star span:last-child').text()  
  49.         sheet.append([rank, name, director_actor, time_, area, genres, rating_score, rating_num, quote])  
  50.         logging.info([rank, name, director_actor, time_, area, genres, rating_score, rating_num, quote])  
  51.         rank += 1 
  52. if __name__ == '__main__':  
  53.     rank = 1  
  54.     for i in range(10):  
  55.         get_data(i)  
  56.     wb.save(filename='movie_info3.xlsx'
【声明】:芜湖站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

相关文章