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 条评论
登录 后参与评论

相关文章

来自专栏大数据和云计算技术

HBase框架基础(二)

HBase的基础框架,将分成几个章节对HBase进行描述,不当之处还望大家批评指正。下面是了解HBase基础架构的第二部分。

1152
来自专栏枕边书

PHP 调用 Go 服务的正确方式 - Unix Domain Sockets

问题 可能是由于经验太少,工作中经常会遇到问题,探究和解决问题的过程总想记录一下,所以我写博客经常是问题驱动,首先介绍一下今天要解决的问题: 服务耦合 我们在开...

25911
来自专栏Python爬虫与数据挖掘

如何利用Python网络爬虫爬取微信朋友圈动态--附代码(下)

前天给大家分享了如何利用Python网络爬虫爬取微信朋友圈数据的上篇(理论篇),今天给大家分享一下代码实现(实战篇),接着上篇往下继续深入。

802
来自专栏https://www.cnblogs.com/L

【Spark篇】---Spark中内存管理和Shuffle参数调优

Spark执行应用程序时,Spark集群会启动Driver和Executor两种JVM进程,Driver负责创建SparkContext上下文,提交任务,tas...

1163
来自专栏用户画像

3.1.4.1 基本分页存储管理方式

非连续分配允许一个程序分散地装入到不相邻的内存分区中,根据分区的大小是否固定分为分页存储管理方式和分段存储管理方式。

541
来自专栏大数据挖掘DT机器学习

利用python爬取人人贷网的数据

人人贷网站需要用户登录才能看到其相应的借贷人信息。也就是说在爬取数据时,需要用户登录。回顾之前的代码,我想是保存cookie这种方法是不能用了。必须找到一种新的...

3625
来自专栏北京马哥教育

架构师必读:Linux 的内存分页管理

内存是计算机的主存储器。内存为进程开辟出进程空间,让进程在其中保存数据。我将从内存的物理特性出发,深入到内存管理的细节,特别是了解虚拟内存和内存分页的概念。

862
来自专栏木头编程 - moTzxx

Laravel 框架集成 UEditor 编辑器的方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

881
来自专栏Netkiller

PHP高级编程之消息队列

PHP高级编程之消息队列 摘要 2015-10-19 第一版 2016-11-31 第二版 目录 1. 什么是消息队列 2. 为什么使用消息队列 3. 什么场合...

3504
来自专栏思考的代码世界

Python网络数据采集之创建爬虫|第00天

1504

扫码关注云+社区