zoukankan      html  css  js  c++  java
  • 猫眼电影的各种爬取方法

    按理说这篇随笔上周就要写的,可用 request 一直获取不到详情页信息,这天在网上看到一个说法,说是在 requests.get 后加个 headers 就好了,试了试果然可以实现,于是重新回顾一下,正好对 pyquery 的使用方法理解的差不多了,今天用三种方法分别介绍一下猫眼电影的爬取。

    一般爬猫眼电影有两种方法,一种就像我前段时间写的豆瓣电影爬取方法一样,可以只获取全部电影所在的详情页内容,然后利用 正则表达式 一个一个提取,另一种就是先获取全部电影所在的详情页内容,在分别获取每个电影对应的详情页内容,再利用 正则表达式pyquery 获取。

    方法一:只获取全部电影所在的详情页内容

    import requests
    from requests.exceptions import RequestException
    from multiprocessing import Pool
    import re
    import json
    
    def get_one_page(url):           # 获取网页的 URL
        try:
            headers = {
                'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
            } # 加上headers,网站认为是浏览器访问,就能爬取猫眼电影
            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.*?>(d+)</i>.*?<a.*?title="(.*?)".*?'
                             +'<p.*?releasetime">(.*?)</p>.*?<i.*?integer">(.*?)</i>'
                             +'.*?fraction">(.*?)</i>.*?</dd>',re.S)
        items = re.findall(pattern, html)
        for item in items:
            yield{
                'index':item[0],
                'title':item[1],
                'releasetime':item[2].strip()[5:], # str.strip()就是把这个字符串头和尾的空格,以及位于头尾的
     	之类给删掉
                'score':item[3]+item[4]
            }
    
    def write_to_file(content):       # 把提取出来的信息写到文件夹
        with open('result.txt','a',encoding='utf8')as f:
            f.write(json.dumps(content,ensure_ascii=False)+'
    ')
            f.close()
    
    def main(offset):
        url = 'http://maoyan.com/board/4?offset=' + str(offset)  # 共提取10个网页内容
        html = get_one_page(url)     # 每个网页对应的信息代码
        for item in parse_one_page(html):
            print(item)
            write_to_file(item)
    
    if __name__ == '__main__':
        pool = Pool()
        pool.map(main,[i*10 for i in range(10)])
        # for i in range(10):
        #     main(i*10)    #for 循环比多进程运行慢,但得到的结果是顺序排列的

    尤其要讲一下

    items = re.findall(pattern, html)

    for item in items:

    yield{

       'index':item[0],
       'title':item[1],
       'releasetime':item[2].strip()[5:], # str.strip()就是把这个字符串头和尾的空格,以及位于头尾的
     	之类给删掉
       'score':item[3]+item[4]

    }

    items是一个字典,里面包含了10个 list ,每个item代表一个 list ,包含一部电影的详细内容, yield 返回的内容必须是 item[0],不能是 items[0]。

    方法二:先获取全部电影所在的详情页内容,在分别获取每个电影对应的详情页内容

    通过观察发现,html 里 有一个 href="/films/1203",刚好对应第二层详情页的 url ,通过正则表达式提取出来,再拼接成字符串,最后经过

    get_page_detail(item) 获取该页内容,最后再通过 pyquery 进行内容爬取,代码如下:
    import requests
    from requests.exceptions import RequestException
    from multiprocessing import Pool
    from pyquery import PyQuery as pq
    import re
    import json
    
    def get_page_index(offset):
        try:
            url = 'http://maoyan.com/board/4?offset=' + str(offset)  # 共提取10个网页内容
            headers = {
                'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
            } # 加上headers,网站认为是浏览器访问,就能爬取猫眼电影
            response = requests.get(url,headers = headers)
            if response.status_code == 200:    # 得到网页的响应
                return response.text
            return None
        except RequestException:
            return None
    
    def parse_page_index(html):   # 获取页面的url
        pattern = re.compile('.*?<dd>.*?<a.*?="(.*?)".*?</a>.*?</dd>',re.S)
        items = re.findall(pattern, html)
        for i in range(10):
            yield(items[i])
    
    def get_page_detail(item):
        try:
            url = 'http://maoyan.com' + str(item)  # 共提取10个网页内容
            headers = {
                'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
            } # 加上headers,网站认为是浏览器访问,就能爬取猫眼电影
            response = requests.get(url,headers = headers)
            if response.status_code == 200:    # 得到网页的响应
                return response.text
            return None
        except RequestException:
            return None
    
    def parse_page_detail(html):
        doc = pq(html)
        title = doc('.movie-brief-container > h3').text()
        score = doc('.movie-stats-container > div:nth-child(1) > div > span > span').text()
        introduce = doc('.active > div:nth-child(1) > div.mod-content > span').text()
        return{
            'title':title,
            'score':score,
        }
    
    def write_to_file(content):       # 把提取出来的信息写到文件夹
        with open('result.txt','a',encoding='utf8')as f:
            f.write(json.dumps(content,ensure_ascii=False)+'
    ')
            f.close()
    
    def main(offset):
        html = get_page_index(offset)     # 每个网页对应的信息代码
        for item in parse_page_index(html):
            html = get_page_detail(item)
            if html:
                result = parse_page_detail(html)
                write_to_file(result)
                print(result)
    
    if __name__ == '__main__':
        # pool = Pool()
        # pool.map(main,[i*10 for i in range(10)])
        for i in range(10):
            main(i*10)    # for循环比多进程运行慢,但得到的结果是顺序排列的

    得分 score 得到的结果不是,应该是编码转换问题,有待进一步解决。

  • 相关阅读:
    【工具】sublime使用技巧
    怎样存钱利息最大及怎样买房付款最省钱问题
    存钱问题
    玛丽莲问题
    用线程做一个火车票购票系统(可以根据需要选择线程个数)
    系统编程拷贝文件或者目录(可以做出一个动态库哦)
    mysql优化-数据库设计基本原则
    项目 数据可视化1
    读书笔记2-三体
    python数据学习3 布林带
  • 原文地址:https://www.cnblogs.com/zhangguoxv/p/10006044.html
Copyright © 2011-2022 走看看