• Ajax爬取豆瓣电影目录(Python)


    下面的分析相当于一个框架,搞懂之后,对于类似的文字爬取,我们也可以实现。就算不能使用Ajax方法,我们也能够使用相同思想去爬取我们想要的数据。

    豆瓣电影排行榜分析

    网址https://movie.douban.com/explore#!type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0

    首先我们打开网页的审查元素,选中Network==》XHR==》电影相关信息网页文件

    筛选并比较以下数据(三个文件数据)

    请求地址

    Request URL:https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0
    
    Request URL:https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20
    
    Request URL:https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=40

    查询参数

    type:movie
    tag:热门
    sort:recommend
    page_limit:20
    page_start:0
    
    type:movie
    tag:热门
    sort:recommend
    page_limit:20
    page_start:20
    
    type:movie
    tag:热门
    sort:recommend
    page_limit:20
    page_start:40

    请求报头

    Host:movie.douban.com
    Referer:https://movie.douban.com/explore
    User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
    X-Requested-With:XMLHttpRequest

    通过比较请求地址和查询参数,得出

    请求地址 = baseurl+type+tag+sort+page_limit+page_start
    
    baseurl:https://movie.douban.com/j/search_subjects?
    type:固定为movie
    tag:关键字,需要将utf-8转换为urlencode
    sort:固定为recommend
    page_limit:表示一页显示的电影数量,固定20
    page_start:表示电影页数,从0开始,20为公差的递增函数

    由此我们获取到了我们需要的数据,可以将爬虫分为三步

    1. 获取网页json格式代码
    2. 从代码中获取电影名和电影海报图片链接
    3. 将获得的图片命名为电影名

    流程

    准备工作

    在函数外部定义伪装的请求报头

    headers={
        'Host': 'movie.douban.com',
        'Referer': 'https://movie.douban.com/explore',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }

    获取json格式代码

    def get_page(page):
        #请求参数
        params={
            'type': 'movie',
            'tag': '奥特曼',
            'sort': 'recommend',
            'page_limit': '20',
            'page_start': page,
        }
        #基本网页链接
        base_url = 'https://movie.douban.com/j/search_subjects?'
        #将基本网页链接与请求参数结合在一起
        url = base_url + urlencode(params)
        try:
            #获取网页代码
            resp = requests.get(url, headers=headers)
            print(url)
            #返回json数据格式代码
            if 200 == resp.status_code:
                print(resp.json())
                return resp.json()
        except requests.ConnectionError:
            return None

    筛选数据

    通过观察电影列表代码文件的preview,进行数据筛选

    def get_image(json):
        if(json.get('subjects')):
            data=json.get('subjects')
            for item in data:
                title=item.get('title')
                imageurl=item.get('cover')
                #返回"信息"字典
                yield {
                    'title':title,
                    'images':imageurl,
                }

    存储图片文件

    def save_page(item):
        #文件夹名称
        file_name = '奥特曼电影大全'
        if not os.path.exists(file_name):
            os.makedirs(file_name)
    
        #获取图片链接
        response=requests.get(item.get('images'))
        #储存图片文件
        if response.status_code==200:
            file_path = file_name + os.path.sep + item.get('title') + '.jpg'
            with open(file_path, 'wb') as f:
                f.write(response.content)

    多线程处理

    def main(page):
        json = get_page(page)
        for item in get_image(json):
            print(item)
            save_page(item)
    
    if __name__ == '__main__':
        pool = Pool()
        pool.map(main, [i for i in range(0, 200, 20)])
        pool.close()
        pool.join()

    总代码

    import requests
    from urllib.parse import urlencode
    import os
    from multiprocessing.pool import Pool
    
    headers={
        'Host': 'movie.douban.com',
        'Referer': 'https://movie.douban.com/explore',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        'X-Requested-With': 'XMLHttpRequest'
    }
    
    def get_page(page):
        #请求参数
        params={
            'type': 'movie',
            'tag': '奥特曼',
            'sort': 'recommend',
            'page_limit': '20',
            'page_start': page,
        }
        #基本网页链接
        base_url = 'https://movie.douban.com/j/search_subjects?'
        #将基本网页链接与请求参数结合在一起
        url = base_url + urlencode(params)
        try:
            #获取网页代码
            resp = requests.get(url, headers=headers)
            print(url)
            #返回json数据格式代码
            if 200 == resp.status_code:
                print(resp.json())
                return resp.json()
        except requests.ConnectionError:
            return None
    
    def get_image(json):
        if(json.get('subjects')):
            data=json.get('subjects')
            for item in data:
                title=item.get('title')
                imageurl=item.get('cover')
                #返回"信息"字典
                yield {
                    'title':title,
                    'images':imageurl,
                }
    
    def save_page(item):
        #文件夹名称
        file_name = '奥特曼电影大全'
        if not os.path.exists(file_name):
            os.makedirs(file_name)
    
        #获取图片链接
        response=requests.get(item.get('images'))
        #储存图片文件
        if response.status_code==200:
            file_path = file_name + os.path.sep + item.get('title') + '.jpg'
            with open(file_path, 'wb') as f:
                f.write(response.content)
    
    def main(page):
        json = get_page(page)
        for item in get_image(json):
            print(item)
            save_page(item)
    
    if __name__ == '__main__':
        pool = Pool()
        pool.map(main, [i for i in range(0, 200, 20)])
        pool.close()
        pool.join()

     本来是准备使用https://movie.douban.com/tag/#/ 不过在后面,刷新网页时,总是出现服务器问题。不过下面的代码还是可以用。

    import requests
    from urllib.parse import urlencode
    import os
    from hashlib import md5
    from multiprocessing.pool import Pool
    
    headers={
        'Host': 'movie.douban.com',
        'Referer': 'https://movie.douban.com/tag/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
    }
    
    def get_page(page):
        params={
            'sort':'U',
            'range':'0,10',
            'tags':'奥特曼',
            'start': page,
        }
        base_url = 'https://movie.douban.com/j/new_search_subjects?'
        url = base_url + urlencode(params)
        try:
            resp = requests.get(url, headers=headers)
            print(url)
            if 200 == resp.status_code:
                print(resp.json())
                return resp.json()
        except requests.ConnectionError:
            return None
    
    def get_image(json):
        if(json.get('data')):
            data=json.get('data')
            for item in data:
                title=item.get('title')
                imageurl=item.get('cover')
                yield {
                    'title':title,
                    'images':imageurl,
                }
    
    def save_page(item):
        file_name='奥特曼大全'+os.path.sep+item.get('title')
        if not os.path.exists(file_name):
            os.makedirs(file_name)
        try:
            response=requests.get(item.get('images'))
            if response.status_code==200:
                file_path = '{0}/{1}.{2}'.format(file_name, md5(response.content).hexdigest(), 'jpg')
                if not os.path.exists(file_path):
                    with open(file_path, 'wb') as f:
                        f.write(response.content)
                else:
                    print('Already Downloaded', file_path)
        except requests.ConnectionError:
            print('Failed to Save Image')
    
    def main(page):
        json = get_page(page)
        for item in get_image(json):
            print(item)
            save_page(item)
    
    if __name__ == '__main__':
        pool = Pool()
        pool.map(main, [i for i in range(0, 200, 20)])
        pool.close()
        pool.join()
  • 相关阅读:
    普林斯顿《算法》笔记(二)
    集成学习之Boosting —— AdaBoost原理
    Bagging与方差
    js中的深复制与浅复制
    Javascript的异步与单线程
    实现Vue的双向绑定
    什么是mvvm设计模式
    什么是虚拟DOM
    vue源码实现的整体流程解析
    Java基础常见英语词汇
  • 原文地址:https://www.cnblogs.com/Mayfly-nymph/p/10780620.html
Copyright © 2020-2023  润新知