网络爬虫之reddit爬取

reddit是一个国外的论坛性质的东西,为了做chatbot,所以准备爬一些数据下来。

准备工作

—— scrapy框架的安装和熟悉

可参考网页:
http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/tutorial.html
http://www.jianshu.com/p/7a146c848388

—— 网页结构分析

用firefox打开reddit,搜索chat
得到的网页为https://www.reddit.com/search?q=chat&type=sr&count=4&before=t5_2uul1
下图是搜索结果页面,然后有很多个分板块,来看看如何一步一步分析得到每一句对话。
注:下面查看xpath的方式都是用Firebug查看的,比较方便

1. 获取同一页上的不同板块

以第二个板块为例,它的链接网页为
https://www.reddit.com/r/online_chat/
它在html文件中的显示为

<a class="search-title may-blank" href="https://www.reddit.com/r/online_chat
/?ref=search_subreddits">
Online
<mark>Chat</mark>
</a>

它的xpath为
/html/body/div[5]/div[2]/div/div/div[2]/header/a
现在来看看第一个板块chat的xpath
/html/body/div[5]/div[2]/div/div/div[1]/header/a/
所以获取的方式为

pages = selector.xpath('/html/body/div[5]/div[2]/div/div/div/header/a/@href').extract()

2. 获取下一页

再来看下一页的网页为https://www.reddit.com/search?q=chat&type=sr&count=3&after=t5_3d7l3

对比第一页的https://www.reddit.com/search?q=chat&type=sr&count=4&before=t5_2uul1
规律不是很明显,所以来看看第一页中的next按钮的html显示

<span class="nextprev">
view more:
<a href="https://www.reddit.com/search?q=chat&type=sr&count=3&after=t5_3d7l3" rel="nofollow next">next ›</a>
</span>

xpath为
/html/body/div[5]/div[2]/div/footer/div/span/a
对比来看看第二页的next的xpath:
/html/body/div[5]/div[2]/div/footer/div/span/a[2]
为什么最后多了一个[2]是因为多了一个prev按钮,所以来看看

<a href="https://www.reddit.com/search?q=chat&type=sr&count=28&after=t5_2t6ze" rel="nofollow next">next ›</a>
#下面是第一页的
<a href="https://www.reddit.com/search?q=chat&type=sr&count=3&after=t5_3d7l3" rel="nofollow next">next ›</a>

找到共同点为都有rel="nofollow next",所以获取方式可以通过把第一页当作特殊情况或者通过这个共同点来获取。
如果采取第一种方案:

next_page = selector.xpath('/html/body/div[5]/div[2]/div/footer/div/span/a[2]/@href').extract()

如果采取第二种方案:

next_page = selector.xpath('/html/body/div[5]/div[2]/div/footer/div/span/a[@rel="nofollow next"]/@href').extract() 

3. 获取板块里面的每个发言页面

看看第一个板块chat板块的结构

# 第一个发言的xpath
/html/body/div[5]/div/div[1]/div[2]/div/p[1]/a

链接到的网站为:
https://www.reddit.com/r/chat/comments/5q77js/rchat_is_seeking_capable_mods_with_css_experience/

# 第二个发言的xpath
/html/body/div[5]/div/div[3]/div[2]/div/p[1]/a

第一个发言在html中的显示:

<a class="title may-blank " data-event-action="title" href="/r/chat/comments/5q77js
/rchat_is_seeking_capable_mods_with_css_experience/" 略</a>

第二个发言在html中的显示:

<a class="title may-blank " data-event-action="title" href="/r/chat/comments/6tivrr/26m_lets_do_it/" 略</a>

共同点就是data-event-action="title"
所以获取方式为:

talks_page = selector.xpath('/html/body/div[5]//div[@data-event-action="title"]/@href').extract()

因为reddit不同板块的结构可能不同,所以的话再看一个板块,第二个板块的第一个发言的xpath为
/html/body/div[5]/div/div[1]/div[2]/div[1]/p[1]/a
可见满足我们的提取方式。

4. 获取板块里面的下一页

/html/body/div[5]/div/div[53]/span/span/a
# html中显示
<a href="https://www.reddit.com/r/online_chat/?count=25&after=t3_6dsebv" rel="nofollow next">next ›</a>
# 第二页的next按钮
/html/body/div[5]/div/div[51]/span/span[3]/a

获取方式为:

next_page = selector.xpath('/html/body/div[5]/div//a[@rel="nofollow next"]/@href').extract()

5. 获取每一个发言页面的对话

先看看发言页面长什么样子

最外圈的xpath为:/html/body/div[5]/div[2]/div[3]

第一个人的评论然后往下依次为:
对应图中的hello
/html/body/div[5]/div[2]/div[3]/+div[1]/+div[2]/form/div/div/p
对应图中的Hi :)
/html/body/div[5]/div[2]/div[3]/+div[1]/+div[3]/div/div[1]/+div[2]/form/div/div/p
对应图中的hello. How are you?
/html/body/div[5]/div[2]/div[3]/+div[1]/+div[3]/div/div[1]/+div[3]/div/div[1]/+div[2]/form/div/div/p

然后下面的第二个人发起的评论为
/html/body/div[5]/div[2]/div[3]/+div[3]/+div[2]/form/div/div/p

可以按照构造规律从外往里提取文本,但是这样比较麻烦,来看看在html中的显示:

<div class="usertext-body may-blank-within md-container ">
<div class="md">
<p>hello</p>
</div>
</div>

发现class="usertext-body may-blank-within md-container "这个都是存在的,算是一个共同点。
然后在html中观察每一个人发起的评论区域的html显示中都会有data-type="comment"。
所以便有一种提取方法:

  1. 提取每个人发起的对话区域:

    comment_zone = selector.xpath('//div[@data-type="comment"]')
    
  2. 用循环提取每一句对话

    for conversation in comment_zone:
        talk = conversation.xpath('//div[@class="usertext-body may-blank-within md-container "]/div/p/text()').extract()
    

但是在每一轮对话中,就像下面这种,有针对一句话的两个人的不同回答,那怎么办?

这时候可以给scrappy定义的item多加一点属性,除了对话本身,还得加一点id之类的标示,每个人发起的回复有一个id,然后后期再处理。
也可以在写py文件时就处理,为后面省一点时,处理逻辑可以是递归。
不过这里因为数量也够大了,所以这种情况就直接忽略或者跳过就好了,省去一些麻烦。

编写爬虫代码

框架使用scrapy

开始爬取

注:上面的代码中可能有细节错误,主要提供一个爬虫的框架和思想介绍,不关注细节

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

推荐阅读更多精彩内容

  • 之前写的那个reddit爬取不含细节,因为我最后爬取没有采用爬取所有的小板块,而是采取了从网页https://ww...
    Ydrivemecrazy阅读 3,333评论 0 3
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,630评论 1 92
  • 声明:本文讲解的实战内容,均仅用于学习交流,请勿用于任何商业用途! 一、前言 强烈建议:请在电脑的陪同下,阅读本文...
    Bruce_Szh阅读 12,588评论 6 28
  • 这是一篇简单文章,主要目的在于展示XPath的不同使用方法,当然,因为个人的喜好,所以示例当然是通过R语言来实现,...
    distiner阅读 2,655评论 0 4
  • 你多少都有来回奔波的经历吧? 或许是异地恋? 或许是照顾孩子? 或许老人生病? 或许工作变动? 又或许是在追求梦想...
    小象站长阅读 563评论 0 1