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

Stella981
• 阅读 954

下面的分析相当于一个框架,搞懂之后,对于类似的文字爬取,我们也可以实现。就算不能使用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,进行数据筛选

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

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()

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

总代码

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()
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Aidan075 Aidan075
3年前
用python爬取4332条粽子数据进行分析,再送15盒粽子给大家
↑点击上方“凹凸数据” 关注星标 文章干货!有福利 ! 端午节快要到了,甜咸粽子之争也快要拉开帷幕。小五准备用Python爬取淘宝上的粽子数据并进行分析,看看有什么发现。(顺便送大家一波福利)爬虫爬取淘宝数据,本次采用的方法是:Selenium控制Chrome浏览器自动化操作\1\。其实我们还可以利用Ajax接口来构造链接,但是非常
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这