通过哪吒豆瓣影评,带你分析python爬虫快速入门

久旱逢甘霖

西安连着几天温度排行全国三甲,也许是哪吒动漫的剧组买通了老天,从踩着风火轮的小朋友首映开始,就全国性的持续高温,还好今天凌晨的一场暴雨,算是将大家从中暑边缘拯救回来了。不知道有多少人看了这部国产动漫,,可惜忙碌的我只能在朋友圈看看好友的观影评价+晒门票。

爬虫解析

最近更新爬虫的文章比较多,对于这种投入量小,回报率高且装13效果好的python方向,大家都比较喜欢。其实单纯的爬虫很简单,麻烦的是网站的接口分析与数据解析。通常我们大量的时间,用在了对网站数据流的分析,最终得到数据接口的过程。这部分的内容,针对不同网站需要单独分析,没有一个可以套的公式,所以讲起来也没有太好的效果。那么,除去了网站分析,刚才提到的数据解析是否有可复用的地方呢?当然...

网站数据解析

说到网站的数据解析,那么我们首先得找一个供我们爬虫的网站,既然刚才提到了哪吒,我们就拿豆瓣评分来举例子吧:


哪吒豆瓣评分

点击网页短评的全部xxx条链接,即可进入该动画的全部影评网页:


电影短评入口

之后我们来看看短评界面的数据结构:
网站结构分析

我们可以看到,所有的评论都包裹在一个class="mod-bd"和id="comments"的div中,这里注意个html的常识,绝大多数的情况下,如果一个标签存在id和class,那么你请优先选择id作为你的定位游标,因为它具备唯一性。当然你也可以使用class定位,但它可能存在多个,如何判断是否唯一呢?这里教你个简单的方法...

console下编写js

我们F12打开浏览器的开发者工具,然后选择Console标签页,通过js代码输入你想了解的class等标签名称即可:

> document.getElementsByClassName("mod-bd").length
< 1
> document.getElementsByClassName("comment").length
< 20
> document.getElementsByTagName('a').length
< 133
> document.getElementsByName("description").length
< 1
js定位
土办法

如果你觉得F12看这很不习惯,就是想搜索,那么你可以再网页上右键+查看源代码(快捷键CTRL+U),但这种方式极其不推荐...


网页源码定位
爬虫获取数据

分析了网页结构,就到了代码筛选网页数据的过程了。通常这个时候我们该考虑两件事,获取网站源码与数据过滤

获取网站源码

首先如何通过代码获取到网页的整体源码,并通过规则完成批量获取。我们点击豆瓣影评的下一页,会看到url如下:
https://movie.douban.com/subject/26794435/comments?start=20&limit=20&sort=new_score&status=P
其中问号以后,是网站get请求是附带的传参,其中只需要关注start=20即可,其他的参数都可以忽略不会影响到最终的数据获取。
所以,我们只需要定制匹配规则后,编写代码:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清风Python
# @Date     : 2019/7/30 2:44
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : MovieComments.py


import requests


class MovieComments:
    def __init__(self):
        self.pages = 1

    def make_urls(self):
        for page in range(self.pages):
            r = requests.get("https://movie.douban.com/subject/26794435/comments?start={}".format(page * 20))
            print(r.text)


if __name__ == '__main__':
    main = MovieComments()
    main.make_urls()

我们先获取第一页的数据,来进行下测试,针对返回的结果,我们找一个关键字确认下,就找刚才那个评分人名字吧丁凯乐,看看有没有

网页数据确认

确认数据获取无误,下来我们就可以适当放开pages的数量,按照你想获取的页数,进行爬虫了。

数据过滤

按照上面的得到了网页的源码只是很小的一步,我们还需要将网页源码内容进行数据过滤,最终得到我们想要的数据...看过刚才的网页分析,我们了解到了需求内容,需要获取每一条影评中的影评人、推荐指数、影评内容、点赞数、评论时间。该怎么过滤出这些数据呢?通常的方式有两种:

  1. 直接使用正则去匹配所需内容
  2. 使用python的BeautifulSoup模块
re与BeautifulSoup比较

有一句话说的好,当一件事情遇到了正则,那么它将变为两件事。这句话的意思不言而喻,正则是一件让人头疼的事情,但为什么使用度还这么高,因为它的高效率。
那么BeautifulSoup有什么优势呢?抛开上纲上线的纯Python模块更加Pythonic的客套话,BeautifulSoup的定位方式与js、selenium、css selector等等同类型语言或者工具都大相径庭,所谓一通百通,学会了一种就相当于学会了一个范围的内容。但还是要说一点,纯python开发的模块,运行效率不如re高...,所以,说了半天你会选择哪个模块进行定位?反正我选BeautifulSoup....

BeautifulSoup
介绍

BeautifulSoup 库的名字取自刘易斯 ·卡罗尔在《爱丽丝梦游仙境》里的同名诗歌:
“美味的汤,绿色的浓汤,
在热气腾腾的盖碗里装!
谁不愿意尝一尝,这样的好汤?
晚餐用的汤,美味的汤!”

这诗歌吧...恩,欣赏不来。

安装&导入

使用pip install beautifulsoup4命令,即可完成安装操作。
导入时,我们需要注意它的名称变更,需使用:from bs4 import BeautifulSoup

使用

当我们将网页的t.text传输给BeautifulSoup时,还需要引入语法分析器,默认使用较多的为lxml和html.parser,之前介绍手机打造python开发者桌面时,说过这两个模块html.parser是python自带的模块,而lxml则需要安装,切安装时在linux等环境下经常报错,但优点是效率高。

元素定位

BeautifulSoup的元素定位方式多种多样,下面我们挑选常用的集中方式进行讲解...为了方便测试,我们将刚才的网页保存至本地。

...
with open('comments.html', 'w', encoding='utf-8') as f:
    f.write(r.text)
...

之后我们在本地读取文件,免得每次去请求豆瓣影评:

# -*- coding: utf-8 -*-
# @Author   : 王翔
# @JianShu  : 清风Python
# @Date     : 2019/7/30 3:32
# @Software : PyCharm
# @version  :Python 3.7.3
# @File     : LearnBeautifulsoup.py

from bs4 import BeautifulSoup

with open('comments.html', encoding='utf-8') as f:
    html = f.read()

soup = BeautifulSoup(html, 'lxml')
标签定位

标签定位方式最为简单,print(soup.h1) >>> <h1>哪吒之魔童降世 短评</h1>
当然它也等同于:
print(soup.find('h1')) >>> <h1>哪吒之魔童降世 短评</h1>
print(soup.html.body.h1) >>> <h1>哪吒之魔童降世 短评</h1>

find与findAll

这两个方法在js、selenium中也有同类的方法,意味查找一个和查找所有。同事findAll返回结果为list,支持列表切片的操作。
find(tag, attributes, recursive, text, keywords)
findAll(tag, attributes, recursive, text, limit, keywords)
一般我们常使用的只要tag和attributes字段。
print(soup.findAll(('h1','title')))
print(soup.findAll("div", {"class":"mod-bd"}))
recursive默认为True,表示递归抓取,如果设置成False,那么仅抓取游标的一级标签,而忽略器所有子标签
limit这是findAll的一个切片操作,类似于print(soup.findAll("div", {"class":"comment"}))[:limit]
keyword为关键字,比如:print(soup.find(id="comments"))。
注意:keyword中由于是使用赋值操作,当遇到class这种类关键字是,需要这么写:soup.find(class_="mod-bd")

巧用attrs
巧用attrs

我们注意到每一个短评数据中,都有一个data-cid的属性,那么当我们巧用该属性,就可以立即定位到每个影评,方式如下:
print(soup.findAll("div", attrs={'data-cid':True}))

子与后代标签

child、children、descendants,都表示标签的子标签,只是descendants表示所有子孙标签,而child和children只是一级子标签,区别在于单个和所有的筛选

兄弟父子标签

next_siblings表示当前标签之后的所有子标签,要注意这个之后的操作,比如之前的comment-item,我们代码这么写:

for i in soup.findAll("div", attrs={'data-cid':True})[-3].next_siblings:
    print(i)

我们扎到本页所有评论后,定位到倒数第三条评论,然后使用next_siblings,那么代码只会找到这条评论之后的-2和-1两条评论。
至于parent和parents就再简单不过了,无非是我限定为到子级标签,之后逆推至它的父级标签:
print(soup.find("div", attrs={'data-cid':True}).parent)我们先定位到一条评论,之后获取其父标签,结果将是得到了整页的20条评论

引入正则

虽然不想单独说正则,但是BeautifulSoup在定位过程中,确实支持正则表达式的匹配使用的,简单举个例子吧:
print(soup.findAll("div", {"class":re.compile("comment-.*?")}))
通过re.compile制定匹配规则,一样可以获取到所有的评论信息...

The End

OK,今天的内容就到这里,如果觉得内容对你有所帮助,欢迎点击文章右下角的“在看”。
期待你关注我的公众号清风Python,如果觉得不错,希望能动动手指转发给你身边的朋友们。
在之后的周一至五清晨7点10分,希望都能让清风Python的知识文章叫醒大家!谢谢……

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,265评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,274评论 1 288
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,087评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,479评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,782评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,218评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,594评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,316评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,955评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,274评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,803评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,177评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,732评论 3 229
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,953评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,687评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,263评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,189评论 2 258

推荐阅读更多精彩内容