首页 > Python爬虫 阅读:32144

Python爬虫抓取猫眼电影排行榜

本节使用 Python 爬虫抓取猫眼电影网 TOP100 排行榜(https://maoyan.com/board/4)影片信息,包括电影名称、上映时间、主演信息。

在开始编写程序之前,首先要确定页面类型(静态页面或动态页面),其次找出页面的 url 规律,最后通过分析网页元素结构来确定正则表达式,从而提取网页信息。

确定页面类型

点击右键查看页面源码,确定要抓取的数据是否存在于页面内。通过浏览得知要抓取的信息全部存在于源码内,因此该页面输属于静态页面。如下所示:
<div class="movie-item-info">
 <p class="name"><a href="/films/1200486" title="我不是药神" data-act="boarditem-click" data-val="{movieId:1200486}">我不是药神</a></p>
 <p class="star">
 主演:徐峥,周一围,王传君
 </p>
<p class="releasetime">上映时间:2018年07月05日</p> </div>

确定url规律

想要确定 url 规律,需要您多浏览几个页面,然后才可以总结出 url 规律,如下所示:
第一页:https://maoyan.com/board/4?offset=0
第二页:https://maoyan.com/board/4?offset=10
第三页:https://maoyan.com/board/4?offset=20
...
第n页:https://maoyan.com/board/4?offset=(n-1)*10

确定正则表达式

通过分析网页元素结构来确定正则表达式,如下所示:
<div class="movie-item-info">
    <p class="name"><a href="/films/1200486" title="我不是药神" data-act="boarditem-click" data-val="{movieId:1200486}">我不是药神</a></p>
    <p class="star">
        主演:徐峥,周一围,王传君
    </p>
<p class="releasetime">上映时间:2018年07月05日</p></div>
使用 Chrome 开发者调试工具来精准定位要抓取信息的元素结构。之所以这样做,是因为这能避免正则表达式的冗余,提高编写正则表达式的速度。正则表达式如下所示:
<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>
编写正则表达式时将需要提取的信息使用(.*?)代替,而不需要的内容(包括元素标签)使用.*?代替。

编写爬虫程序

下面使用面向对象的方法编写爬虫程序,主要编写四个函数,分别是请求函数、解析函数、保存数据函数、主函数。
from urllib import request
import re
import time
import random
import csv
from ua_info import ua_list
# 定义一个爬虫类
class MaoyanSpider(object): 
 # 初始化
 # 定义初始页面url
  def __init__(self):
    self.url = 'https://maoyan.com/board/4?offset={}'
 
 # 请求函数
  def get_html(self,url):
    headers = {'User-Agent':random.choice(ua_list)}
    req = request.Request(url=url,headers=headers)
    res = request.urlopen(req)
    html = res.read().decode()
    # 直接调用解析函数
    self.parse_html(html)
 
 # 解析函数
  def parse_html(self,html):
 # 正则表达式
    re_bds = '<div class="movie-item-info">.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?class="releasetime">(.*?)</p>'
 # 生成正则表达式对象
    pattern = re.compile(re_bds,re.S)
    # r_list: [('我不是药神','徐峥,周一围,王传君','2018年07月05日'),...] 列表元组
    r_list = pattern.findall(html)
    self.save_html(r_list)
  # 保存数据函数,使用python内置csv模块
  def save_html(self,r_list):
 #生成文件对象 
    with open('maoyan.csv','a',newline='',encoding="utf-8") as f:
 #生成csv操作对象
      writer = csv.writer(f)
 #整理数据
      for r in r_list:
        name = r[0].strip()
        star = r[1].strip()[3:]
        # 上映时间:2018年07月05日
 # 切片截取时间
        time = r[2].strip()[5:15]
        L = [name,star,time]
 # 写入csv文件
        writer.writerow(L)
        print(name,time,star)
 # 主函数
  def run(self):
 #抓取第一页数据
    for offset in range(0,11,10):
      url = self.url.format(offset)
      self.get_html(url)
      #生成1-2之间的浮点数
      time.sleep(random.uniform(1,2))
# 以脚本方式启动
if __name__ == '__main__':
  #捕捉异常错误
  try:
    spider = MaoyanSpider()
    spider.run()
  except Exception as e:
    print("错误:",e)
输出结果:

我不是药神 2018年07月05日 徐峥,周一围,王传君
肖申克的救赎 1994年09月10日 蒂姆·罗宾斯,摩根·弗里曼,鲍勃·冈顿
绿皮书 2019年03月01日 维果·莫腾森,马赫沙拉·阿里,琳达·卡德里尼
海上钢琴师 2019年11月15日 蒂姆·罗斯,比尔·努恩,克兰伦斯·威廉姆斯三世
小偷家族 2018年08月03日 中川雅也,安藤樱,松冈茉优
霸王别姬 1993年07月26日 张国荣,张丰毅,巩俐
哪吒之魔童降世 2019年07月26日 吕艳婷,囧森瑟夫,瀚墨
美丽人生 2020年01月03日 罗伯托·贝尼尼,朱斯蒂诺·杜拉诺,赛尔乔·比尼·布斯特里克
这个杀手不太冷 1994年09月14日 让·雷诺,加里·奥德曼,娜塔莉·波特曼
盗梦空间 2010年09月01日 莱昂纳多·迪卡普里奥,渡边谦,约瑟夫·高登-莱维特

AltStyle によって変換されたページ (->オリジナル) /