• Python爬虫----抓取豆瓣电影Top250


    有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息。

    1.观察url

    首先观察一下网址的结构 http://movie.douban.com/top250?start=0&filter=&type= :

    可以看到,问号?后有三个参数 start、filter、type,其中start代表页码,每页展示25部电影,0代表第一页,以此类推25代表第二页,50代表第三页...

    filter顾名思义,是过滤已经看过的电影,filter和type在这里不重要,可以不管。

    2.查看网页源代码

    打开上面的网址,查看源代码,可以看到信息的展示结构如下:

     1 <ol class="grid_view">
     2         <li>
     3             <div class="item">
     4                 <div class="pic">
     5                     <em class="">1</em>
     6                     <a href="http://movie.douban.com/subject/1292052/">
     7                         <img alt="肖申克的救赎" src="http://img3.douban.com/view/movie_poster_cover/ipst/public/p480747492.jpg" class="">
     8                     </a>
     9                 </div>
    10                 <div class="info">
    11                     <div class="hd">
    12                         <a href="http://movie.douban.com/subject/1292052/" class="">
    13                             <span class="title">肖申克的救赎</span>
    14                                     <span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span>
    15                                 <span class="other">&nbsp;/&nbsp;月黑高飞(港)  /  刺激1995(台)</span>
    16                         </a>
    17 
    18 
    19                             <span class="playable">[可播放]</span>
    20                     </div>
    21                     <div class="bd">
    22                         <p class="">
    23                             导演: 弗兰克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·罗宾斯 Tim Robbins /...<br>
    24                             1994&nbsp;/&nbsp;美国&nbsp;/&nbsp;犯罪 剧情
    25                         </p>
    26 
    27                         
    28                         <div class="star">
    29                                 <span class="rating5-t"><em>9.6</em></span>
    30                                 &nbsp;<span>646374人评价</span>
    31                         </div>
    32 
    33                             <p class="quote">
    34                                 <span class="inq">希望让人自由。</span>
    35                             </p>
    36                     </div>
    37                 </div>
    38             </div>
    39         </li>

    其中<em class="">1</em>代表排名,<span class="title">肖申克的救赎</span>代表电影名,其他信息的含义也很容易能看出来。

    于是接下来可以写正则表达式:

     1 pattern = re.compile(u'<div.*?class="item">.*?<div.*?class="pic">.*?'
     2                              + u'<em.*?class="">(.*?)</em>.*?'
     3                              + u'<div.*?class="info">.*?<span.*?class="title">(.*?)'
     4                              + u'</span>.*?<span.*?class="title">(.*?)</span>.*?'
     5                              + u'<span.*?class="other">(.*?)</span>.*?</a>.*?'
     6                              + u'<div.*?class="bd">.*?<p.*?class="">.*?'
     7                              + u'导演: (.*?)&nbsp;&nbsp;&nbsp;'
     8                              + u'主演: (.*?)<br>'
     9                              + u'(.*?)&nbsp;/&nbsp;(.*?)&nbsp;/&nbsp;'
    10                              + u'(.*?)</p>'
    11                              + u'.*?<div.*?class="star">.*?<em>(.*?)</em>'
    12                              + u'.*?<span>(.*?)人评价</span>.*?<p.*?class="quote">.*?'
    13                              + u'<span.*?class="inq">(.*?)</span>.*?</p>', re.S)

    在此处flag参数re.S代表多行匹配。

    3.使用面向对象的设计模式编码

    代码如下:

     1 # -*- coding:utf-8 -*-
     2 __author__ = 'Jz'
     3 import urllib2
     4 import re
     5 import sys
     6 
     7 class MovieTop250:
     8     def __init__(self):
     9         #设置默认编码格式为utf-8
    10         reload(sys)
    11         sys.setdefaultencoding('utf-8')
    12         self.start = 0
    13         self.param = '&filter=&type='
    14         self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64)'}
    15         self.movieList = []
    16         self.filePath = 'D:/coding_file/python_file/File/DoubanTop250.txt'
    17     
    18     def getPage(self):
    19         try:
    20             URL = 'http://movie.douban.com/top250?start=' + str(self.start)
    21             request = urllib2.Request(url = URL, headers = self.headers)
    22             response = urllib2.urlopen(request)
    23             page = response.read().decode('utf-8')
    24             pageNum = (self.start + 25)/25
    25             print '正在抓取第' + str(pageNum) + '页数据...' 
    26             self.start += 25
    27             return page
    28         except urllib2.URLError, e:
    29             if hasattr(e, 'reason'):
    30                 print '抓取失败,具体原因:', e.reason
    31     
    32     def getMovie(self):
    33         pattern = re.compile(u'<div.*?class="item">.*?<div.*?class="pic">.*?'
    34                              + u'<em.*?class="">(.*?)</em>.*?'
    35                              + u'<div.*?class="info">.*?<span.*?class="title">(.*?)'
    36                              + u'</span>.*?<span.*?class="title">(.*?)</span>.*?'
    37                              + u'<span.*?class="other">(.*?)</span>.*?</a>.*?'
    38                              + u'<div.*?class="bd">.*?<p.*?class="">.*?'
    39                              + u'导演: (.*?)&nbsp;&nbsp;&nbsp;'
    40                              + u'主演: (.*?)<br>'
    41                              + u'(.*?)&nbsp;/&nbsp;(.*?)&nbsp;/&nbsp;'
    42                              + u'(.*?)</p>'
    43                              + u'.*?<div.*?class="star">.*?<em>(.*?)</em>'
    44                              + u'.*?<span>(.*?)人评价</span>.*?<p.*?class="quote">.*?'
    45                              + u'<span.*?class="inq">(.*?)</span>.*?</p>', re.S)
    46         while self.start <= 225:
    47             page = self.getPage()
    48             movies = re.findall(pattern, page)
    49             for movie in movies:
    50                 self.movieList.append([movie[0], movie[1], movie[2].lstrip('&nbsp;/&nbsp;'), 
    51                       movie[3].lstrip('&nbsp;/&nbsp;'), movie[4], 
    52                       movie[5], movie[6].lstrip(), movie[7], movie[8].rstrip(),
    53                       movie[9], movie[10], movie[11]])
    54     
    55     def writeTxt(self):
    56         fileTop250 = open(self.filePath, 'w')
    57         try:
    58             for movie in self.movieList:
    59                 fileTop250.write('电影排名:' + movie[0] + '
    ')
    60                 fileTop250.write('电影名称:' + movie[1] + '
    ')
    61                 fileTop250.write('外文名称:' + movie[2] + '
    ')
    62                 fileTop250.write('电影别名:' + movie[3] + '
    ')
    63                 fileTop250.write('导演姓名:' + movie[4] + '
    ')
    64                 fileTop250.write('参与主演:' + movie[5] + '
    ')
    65                 fileTop250.write('上映年份:' + movie[6] + '
    ')
    66                 fileTop250.write('制作国家/地区:' + movie[7] + '
    ')
    67                 fileTop250.write('电影类别:' + movie[8] + '
    ')
    68                 fileTop250.write('电影评分:' + movie[9] + '
    ')
    69                 fileTop250.write('参评人数:' + movie[10] + '
    ')
    70                 fileTop250.write('简短影评:' + movie[11] + '
    
    ')
    71             print '文件写入成功...'
    72         finally:
    73             fileTop250.close()
    74     
    75     def main(self):
    76         print '正在从豆瓣电影Top250抓取数据...'
    77         self.getMovie()
    78         self.writeTxt()
    79         print '抓取完毕...'
    80 
    81 DouBanSpider = MovieTop250()
    82 DouBanSpider.main()

    代码比较简单,最后将信息写入一个文件,没有什么需要解释的地方。

    4.运行截图

    5.问题说明

    打开文件浏览时发现有个别电影没有抓取下来或者信息中出现html代码,后来排查发现是因为豆瓣有部分电影的信息不全,缺少主演等导致html代码出现差异而导致正则表达式没有匹配到或者匹配出错。

  • 相关阅读:
    微信小程序开发工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理问题
    微信小程序 带参调用后台接口 循环渲染页面 wx.request wx:for
    三下乡感悟心得体会
    Mysql通过Adjacency List(邻接表)存储树形结构
    java的List中使用filter过滤出符合特定条件的元素List
    mybatis报表,动态列与查询参数+行列转换
    mysql行转列转换
    spring配置jackson不返回null值
    mybatis动态列名
    查出最新记录
  • 原文地址:https://www.cnblogs.com/jzincnblogs/p/4899348.html
Copyright © 2020-2023  润新知