zoukankan      html  css  js  c++  java
  • 【爬虫】-爬取猫眼TOP100

    原文崔庆才《python3网络爬虫实战》

    本文为自学记录,如有侵权,请联系删除

    目标:

    熟悉正则表达式,以及爬虫流程

    获取猫眼TOP100榜单

    1、网站分析

    目标站点为http://www.manyan.com/board/4,需要获取网站TOP100榜单的影片名称、主演、上映时间、地区、评分等信息都直接显示在network对应的response中,可解析对应的html进行获取。且从第1页到第二页,URL变成http://maoyan.com/board/4?offset=10,比之前多了参数offset=10,对比第2页第3页发现该参数即为翻页参数。

    2、获取首页

    实现步骤:定义get_one_page()方法,传入url参数,将抓取的页面结果返回,通过main()方法调用。

    # 首页
    import requests
    
    def get_one_page(url):
    # 输入headers信息伪装为浏览器 headers = { 'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36' } response = requests.get(url, headers=headers) if response.status_code ==200: return response.text return None def main(): url = 'http://www.maoyan.com/board/4' html = get_one_page(url) print(html) main()

     即可把response中的html信息获取下来

    2、正则提取

    一部电影信息对应的源代码是一个dd的节点

    html = '''
    <dd>
                            <i class="board-index board-index-1">1</i>
        <a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}">
          <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" />
          <img data-src="https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" />
        </a>
        <div class="board-item-main">
          <div class="board-item-content">
                  <div class="movie-item-info">
            <p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p>
            <p class="star">
                    主演:张国荣,张丰毅,巩俐
            </p>
    <p class="releasetime">上映时间:1993-01-01</p>    </div>
        <div class="movie-item-number score-num">
    <p class="score"><i class="integer">9.</i><i class="fraction">5</i></p>        
        </div>
    
          </div>
        </div>
    
                    </dd>
    '''
    

      获取排名信息

    import re
    result = re.search('<dd>.*?board-index.*?>(.*?)</i>', html, re.S)
    print(result.group(1))

      获取电影图片

    tp = re.search('<dd>.*?data-src="(.*?)@.*?c"',html, re.S)
    

      获取电影名称

    mc = re.search('<dd>.*?name">.*?>(.*?)</a>',html,re.S)
    

      获取主演

    zy = re.search('<dd>.*?star">(.*?)</p>',html,re.S)
    

      获取发布时间

    fb = re.search('<dd>.*?releasetime">(.*?)</p>', html ,re.S)
    

      获取评分

    pf = re.search('<dd>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>',html,re.S)
    

      全部链接起来

    <dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)@.*?c.*?name">.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>
    

       这样一个正则表达式可以匹配一个电影的结果,里面匹配了7个信息,接下来通过findall() 方法提取所有的内容。

    def parse_one_page(html):
    # 把正则表达式编译成一个正则表达式对象,方便复用 pattern = re.compile( '<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)@.*?c.*?name">.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>', re.S ) items = re.findall(pattern, html) print(items) def main1(): html = ''' <dd> <i class="board-index board-index-1">1</i> <a href="/films/1203" title="霸王别姬" class="image-link" data-act="boarditem-click" data-val="{movieId:1203}"> <img src="//s0.meituan.net/bs/?f=myfe/mywww:/image/loading_2.e3d934bf.png" alt="" class="poster-default" /> <img data-src="https://p1.meituan.net/movie/20803f59291c47e1e116c11963ce019e68711.jpg@160w_220h_1e_1c" alt="霸王别姬" class="board-img" /> </a> <div class="board-item-main"> <div class="board-item-content"> <div class="movie-item-info"> <p class="name"><a href="/films/1203" title="霸王别姬" data-act="boarditem-click" data-val="{movieId:1203}">霸王别姬</a></p> <p class="star"> 主演:张国荣,张丰毅,巩俐 </p> <p class="releasetime">上映时间:1993-01-01</p> </div> <div class="movie-item-number score-num"> <p class="score"><i class="integer">9.</i><i class="fraction">5</i></p> </div> </div> </div> </dd> ''' items = parse_one_page(html) print(items) main1()

      结果

    3、写入文件

    通过JSON库的jumps()实现字典的序列化,并指定ensure_ascii参数为False ,保证输出结果是中文,而不是Unicode编码

    def write_to_file(content):
        with open('result.txt','w',encoding='utf-8') as f:
            f.write(json.jumps(content, ensure_ascii=False)+'
    ')
    

    4、分页爬取

    if __name__=='__main__':
        for i in range(10):
            main(offset=i*10)
    

    5、整合代码

    # 抓去首页
    import requests
    import re
    import json
    import time
    from requests.exceptions import RequestException
    
    def get_one_page(url):
        try:
            headers = {
                'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
            }
            response = requests.get(url, headers=headers)
            if response.status_code ==200:
                return response.text
            return None
        except RequestException:
            return  None
    
    
    def parse_one_page(html):
        pattern = re.compile(
            '<dd>.*?board-index.*?>(.*?)</i>.*?data-src="(.*?)@.*?c.*?name">.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>.*?integer">(.*?)</i>.*?fraction">(.*?)</i>',
            re.S
        )
        items = re.findall(pattern, html)
        for item in items:
            yield {
                'index':item[0],
                'image':item[1],
                'title':item[2],
                # 去除首尾空格,从第4位开始
                'actor':item[3].strip()[3:],
                'time': item[4].strip()[5:],
                'sorce':item[5]+item[6]
            }
    
    def write_to_file(content):
        with open('result.txt','w',encoding='utf-8') as f:
            f.write(json.dumps(content, ensure_ascii=False)+'
    ')
    
    
    def main(offset):
        url = 'http://www.maoyan.com/board/4?offset=' + str(offset)
        html = get_one_page(url)
        for item in parse_one_page(html):
            print(item)
            write_to_file(item)
    
    if __name__=='__main__':
        for i in range(10):
            main(offset=i*10)
            time.sleep(1)
    

      结果:

  • 相关阅读:
    Android ADB关闭Selinux ( adb shell setenforce 0 )
    通过windowmanager在camera界面上显示内容
    Android Handler类 发送消息-post()和postDelay(), Looper讲解
    Ubuntu下的log日志查看器
    Ubuntu下 安卓 adb 命令报:“insufficient permissions for device: user in plugdev group; ”问题的解决办法
    java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libjni_i
    为 Linux 应用程序编写 DLL
    android Camera 之 ZSL
    Android Studio 导入 Android 系统模块并编译和调试
    微服务架构设计
  • 原文地址:https://www.cnblogs.com/zheng1076/p/10688284.html
Copyright © 2011-2022 走看看