Python小白使用爬虫提取豆瓣电视剧数据

我…我…我是看着好久没更新Python的文章了,于是我将魔爪伸向了Python来水一文

准备工作

在开始干爬虫之前你肯定要安装Python的环境,也就是Python语言的解释器,还有Python的编辑器,Pycharm。这些之前都有说过,可以参考之前的分类文章

为了能够敏捷而又不失优雅地完成这次操作,我慎(tou)重(lan)选择了直接进行实战演练,废话不多说,开干

分析豆瓣URL

写爬虫之前肯定是要分析链接的,不然你怎么去爬,而且爬取数据我们尽量去找一些返回json数据的URL,因为json更好处理数据,但是并不是所有的站点返回数据都是json

怎么找返回json的URL呢?

  1. 打开浏览器的抓包工具,查看网络请求,当然你也可以使用FD等这些专业的工具
  2. 把浏览器网页切换到手机版

国产剧 – 电视 – 豆瓣的URL:https://m.douban.com/tv/chinese

然后我们按下F12打开浏览器的抓包工具,查看network这一栏就可以看到有一条这样的请求

items?os=ios&for_mobile=1&callback=jsonp1&start=0&count=18&loc_id=108288&_=1527155131544

点击它,看它的Request URL:

https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_domestic_hot/items?os=ios&for_mobile=1&callback=jsonp1&start=0&count=18&loc_id=108288&_=1527155131544

我们会发现我们访问的URL跟他请求是URL不同,然后我们查看它的Response就会看到一些json数据

浏览器的抓包工具

美剧 – 电视 – 豆瓣的URL:https://m.douban.com/tv/american

美剧的Request URL:

https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_american_hot/items?os=ios&for_mobile=1&callback=jsonp1&start=0&count=18&loc_id=108288&_=1527154794289

分析一下这两个URL

/filter_tv_domestic_hot/是根据这个参数来判断电视剧的类型,strat的值也会变,这个表示我们已经获取的数量

请求这个URL能够返回一个json字符串,我们能够将它转换为一个Python字典,就能够从中提取数据了,但是我们发现这个请求返回的数据中有一个jsonp1,这个jsonp1中间包括的才是一个字典,而外面这个jsonp1并不是我们所需要的数据

数据带有jsonp1

无论在爬其他网站的时候还是爬豆瓣的时候,如果发现返回的数据包含这个jsonp1、jsonp2…99在前面的时候,说明它的URL参数包含callback=jsonp1,要解决这个问题的话,我们就将这个参数删除掉,就可以将响应变成一个非常完美的json字符串

处理后得到的json数据

构建代码

骚气的分析了这么多,下面开始代码,新建一个py文件

定义一个run方法,主要实现我们的逻辑,先写一下我们的思路

def run():
    #1.url_list 带请求的是临时地址
    #2.发送请求 获取响应
    #3.提取数据
    #4.保存

然后进行异常处理+请求数据

from retrying import retry

@retry(stop_max_attempt_number=3)
def _parse_url(url):
    print("*"*100)
    r = requests.get(url,headers=headers,timeout=5) #可能会超时报错
    assert r.status_code == 200 #可能会请求不成功报错
    return r.content.decode()

def parse_url(url):
    try:
        html = _parse_url(url)
    except Exception as e:
        print("报错了:",e)
        html = None
    return html

完整的代码如下

import json
import requests
from retrying import retry

headers = {"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
           "Referer":"https://m.douban.com/tv/american"}#referer 豆瓣新加的

@retry(stop_max_attempt_number=3)
def _parse_url(url):
    print("*"*100)
    r = requests.get(url,headers=headers,timeout=5) #可能会超时报错
    assert r.status_code == 200 #可能会请求不成功报错
    return r.content.decode()

def parse_url(url):
    try:
        html = _parse_url(url)
    except Exception as e:
        print("报错了:",e)
        html = None
    return html

def get_url_list():#1.url_list 带请求的是临时地址
    url_list = [
        {
            "url_temp":"https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_american_hot/items?os=ios&for_mobile=1&start={}&count=18",
            "country":"UK"
        },
        {
            "url_temp":"https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_english_hot/items?os=ios&for_mobile=1&start={}&count=18",
            "country": "US"
        },
       {
           "url_temp": "https://m.douban.com/rexxar/api/v2/subject_collection/filter_tv_domestic_hot/items?os=ios&for_mobile=1&start={}&count=18",
           "country": "China"
       }
    ]
    return url_list

def get_content_list(json_response):
    dict_response = json.loads(json_response)
    content_list = dict_response["subject_collection_items"]
    total_num = dict_response["total"]
    return  content_list,total_num

def save_content_list(content_list):
    for content in content_list:
        print(content)
        print("*"*100)


def run():
    #1.url_list 带请求的是临时地址
    url_list_temp = get_url_list()
    for temp in url_list_temp:
        num = 0
        total_num = 100
        while num<=total_num+18:
            url = temp["url_temp"].format(str(num))
            #2.发送请求 获取响应
            json_response = parse_url(url)
            #3.提取数据
            content_list,total_num = get_content_list(json_response)
            #4.保存
            for content in content_list: #添加国家信息
                content["country"] = temp["country"]
            save_content_list(content_list)
            num += 18



if __name__ == '__main__':
    run()

反爬虫一些问题

有时候可能爬取不出来数据,这就说明豆瓣进行了升级或者你的爬虫被封禁了

单个ip单个用户在短时间内请求网站数据过快,都会被豆瓣的反爬虫机制发现并判断为机器操作而封禁,解决的方法有几种

1.使用ip代理池,隔一段时间随机换一个ip

2.降低爬取速度,设置爬虫间隔时间

3.将爬取内容分块,分时间段爬取

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏iKcamp

iKcamp|基于Koa2搭建Node.js实战(含视频)☞ HTTP请求

POST/GET请求——常见请求方式处理 ?? iKcamp 制作团队 原创作者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃 文案校对:李益、大力...

35614
来自专栏CSDN技术头条

QtQuick 系列教程之 QML 与 C++ 交互

QML 作为一种灵活高效的界面开发语言已经越来越得到业界的认可。QML 负责界面,C++ 负责逻辑,这也是 Qt 官方推荐的开发方式。那么 QML 与 C++ ...

1113
来自专栏苍云横渡学习笔记

【第三部分-django博客从搭建到部署】一个完整Django入门指南

【学习目录】 【第一部分-django博客从搭建到部署】一个完整的Django入门指南学习笔记 【第二部分-django博客从搭建到部署】一个完整的Django...

2755
来自专栏杨建荣的学习笔记

vi的补充学习(r4笔记第25天)

今天突然发现vi虽然用了些日子了,但是常用的一些命令之外,还是有些命令比较生疏,简单总结了一下,然后自己在vi里面编辑了一把,效果还不错。 对于大家比较熟悉且常...

32410
来自专栏崔庆才的专栏

利用Scrapy爬取所有知乎用户详细信息并存至MongoDB

本节分享一下爬取知乎用户所有用户信息的Scrapy爬虫实战。本节目标本节要实现的内容有:从一个大V用户开始,通过递归抓取粉丝列表和关注列表,实现知乎所有用户的详...

1.5K1
来自专栏技术博文

ueditor富文本编辑器 修改框宽度和高度的方法

在使用ueditor的时候,用的textarea <textarea name="content" id="myEditor">这里写这条规则的回复内容</te...

3057
来自专栏Python爬虫与算法进阶

Python爬虫入门(二)解析源码

上一期讲了如何获取网页源码的方法,这一期说一说怎么从其中获得我们需要的和数据。 解析网页的方法很多,最常见的就是BeautifulSoup和正则了,其他的像xp...

2494
来自专栏Python入门

使用Python这么多年,才发现Python还有这些实用的功能和特点

在使用Python多年以后,我偶然发现了一些我们过去不知道的功能和特性。一些可以说是非常有用,但却没有充分利用。考虑到这一点,我编辑了一些你应该了解的Pytho...

741
来自专栏Python与爬虫

爬虫入门到精通-爬虫之异步加载(实战花瓣网)

本文章属于爬虫入门到精通系统教程第八讲 本次我们会讲解两个知识点 异步加载 headers中的Accept 本次我们要抓取的是花瓣网美女照片美女花瓣,陪你做生活...

37615
来自专栏禁心尽力

后台模板管理系统___左侧菜单数据的异步加载

 对于搞Java的我来说,前端JS我是有点愚冻,今天在我的博客地盘我就悄悄发布一篇没有技术含量的文章,这次怎么说我也是完完整整的把公司后台管理系统的菜单异步加...

2569

扫码关注云+社区