腾讯、网易、新浪新闻网站爬虫编写记录及评论格式分析

作者:reetsee.com首席运营官

http://blog.csdn.net/qq_17754181/article/details/45179667

至于下面说到的东西要解决什么问题,各位可以先看看这个网站(我毕设的初步结果,目前还在优化中,包括代码结构还有UI设计):http://news.reetsee.com/

这个网站要实现以下功能:从腾讯新闻、网易新闻、新浪新闻中(当然以后可能会更多其它新闻网站)通过代码自动分析出哪些新闻内容是相似的,然后把相似的内容组织到一起,例如三个网站都有“北京成功申奥”这样的新闻,这个网站会自动把三条新闻归到一起,然后把三个新闻网站的热门评论都下载下来,按照时间排序,最后通过代码计算出一段“评论概括”,因为有的人很懒,看新闻基本就是看了标题然后看评论,看评论可能只看热门评论,看热门评论可能还看那种被顶得最多的,所以我就这么帮下这些懒人了……哈哈哈。

这个网站的所有内容可以说都是通过爬虫抓取下来了,我的工作只不过是将爬虫获取的内容进行了组织然后重新展现。

1 新闻格式规范化

我在同学介绍下选择了Python的Scrapy爬虫框架进行爬虫编写。要在自己的网站上展示新闻内容,就应该将下载好的新闻按照统一的格式处理好,这样前端(网页端)才能够方便地处理、展示。一篇新闻有以下几个需要关注的地方:

  1. 新闻标题
  2. 新闻正文
  3. 新闻时间

由于要知道新闻的来源以及对应的评论,所以加上这两项:4. 新闻来源,5. 新闻评论地址。

那么最终在我这里,一篇处理后的新闻格式应该是这样的(这里使用类似json的格式表示,“[]”表示一个数组,“{}”表示一个字典):

{
    'source'   : '来源网站',
    'date'     : '时间(长度8位,如20140501)',
    'contents' : {
            'link'    : '新闻详细内容页面的地址',
            'title'   : '新闻标题',
            'passage' : '新闻正文',
             },
    'comments' : {
            'link' : '新闻对应的评论页面地址',
             },
}

如果有人问既然已经有了新闻的地址页面,为什么还要将新闻标题、新闻正文这些内容保存到本地呢?因为要在本地对新闻进行分类,就必须将这些内容下载下来。

上面的格式只是一个初步的统一格式,最终的格式相比这个可能会有小变化,这个后面再说。

2 评论格式规范化

要在我的网站对评论进行展示,就要有统一的格式,通常评论的要素包括三个:

  1. 用户名
  2. 评论时间
  3. 评论内容

由于我要标注评论的来源,所以再加一个:4. 评论来源,那么最终被我处理过的评论格式如下:

{
    'source' : '来自哪个新闻网站',
    'user' : '用户名',
    'time' : '10位长度的时间戳', //转换成时间戳是为了方便以后排序
    'content' : '评论内容'
}

那么最终重新按照时间排序后的评论列表格式应该是像下面这样的:

[
    {
        'source' : '',
        'user' : '',
        'time' : '',
        'content' : ''
    },
    {
        'source' : '',
        'user' : '',
        'time' : '',
        'content' : ''
    },
    {
        'source' : '',
        'user' : '',
        'time' : '',
        'content' : ''
    },
    ...
]

这里先规范好最终的评论格式,下面针对评论部分的讲解设计就有头有据了。

另外就是评论并不需要爬虫下载!因为评论是实时更新的,不像新闻,基本上发布了就不怎么变化了。因为评论的内容是在用户点击某条新闻后才通过HTTP请求获取的。

3 URL规则分析

3.1 腾讯新闻

其实整个分析下来,我觉得腾讯的URL地址格式是最容易弄清楚的,对于下面的内容,打了黄色背景色的是一个分析说明,其中用了红色字体的代表这个地方是依据新闻的不同而变化的,聪明的你们一定一看就知道是什么意思了。在看下面的内容时,可以自己把这些URL敲到地址栏中尝试一下,其次是使用CHROME或者百度浏览器的同学,强烈建议安装“FeHelper”这个插件,地址是:https://chrome.google.com/webstore/detail/web%E5%89%8D%E7%AB%AF%E5%8A%A9%E6%89%8Bfehelper/pkgccpejnmalmdinmhkkfafefagiiiad?hl=zh-CN

这个东西的作用是能够直接将JSON格式的内容美化成很漂亮的非常容易读到的内容,例如这样:

这个是其中一个功能,还有很多非常赞的功能。

新闻(非专题类)地址格式 :http://news.qq.com/a/8位日期/新闻ID.htm,例如:http://news.qq.com/a/20140113/012246.htm

新闻页面获取评论数量的方法:http://coral.qq.com/article/评论页ID(即cmt_id)/commentnum?callback=_cbSum&source=1&t=随机数(怀疑是时间戳,但是好像没什么用),例如:http://coral.qq.com/article/1004703995/commentnum?callback=_cbSum&source=1&t=0,实际上这个用不到。

新闻的所有评论页面地址 :http://coral.qq.com/评论ID(即cmt_id),例如:http://coral.qq.com/1004703995

热门评论的链接格式如下 :http://coral.qq.com/article/评论页ID(即cmt_id)/hotcomment?reqnum=显示数目&callback=myHotcommentList&_=时间戳+3位随机整数(共10+3=13位),http://coral.qq.com/article/1004703995/hotcomment?reqnum=10&callback=myHotcommentList&_=1389617814425

现在开始分析一下腾讯新闻评论中的字段,比起网易新闻的简直是太臃肿了,那么就直接说关心的内容了(请直接点击上面热门评论的那条URL、或者复制到你的地址栏,回车后查看结果,与下面的内容比对):

  1. targetid就是新闻的id;
  2. time就是时间戳,有了这个可以转换成公元时间;
  3. content就是回复的内容(这位网友真是热心回复这么多);
  4. up就是人家给的赞的数量;
  5. userinfo中的nick就是用户名了,后面竟然还有对应的腾讯微博的用户信息。

还记得在“评论规范化”中定的格式吗?现在我们就从json格式找到一个将其规范化的方法,假设热门评论连接中返回的json格式的变量名为js,i为遍历时的下标,那么用下面这个方法进行评论格式的规范化:

{
    'source' : 'tencent',
    'user' : js['data']['commentid'][i]['userinfo']['nick'],
    'time' : js['data']['commentid'][i]['time'], //原格式就是10位时间戳了不用转换
    'content' : js['data']['commentid'][i]['content']
}

腾讯新闻的算是搞掂了。

3.2 网易新闻

新闻(非专题类)地址格式 :http://news.163.com/年份/日期(四位)/数字/新闻ID.html,例如http://news.163.com/14/0114/19/9IISVTCG0001124J.html

新闻页面获取评论数量的方法:查找”totalCount“就是评论数目,新闻ID就是”threadId“,讨论版面就是”boardId“,这个js是inline的,直接就放到网页中了。

新闻的所有评论页面地址:http://comment.news.163.com/boardId/新闻ID.html,例如http://comment.news.163.com/news_guonei8_bbs/9IISVTCG0001124J.html。关于boardId及新闻ID,请参见上面一项。

在该页面下评论数目为:很有可能在data变量的tcount中。即“data.tcount”

其中正常的评论链接格式如下:http://comment.news.163.com/cache/newlist/news_guonei8_bbs/9IISVTCG0001124J_1.html,但是会有乱码,评论之间通过”return tiePage.showPage(4);“

热门评论的链接格式如下:http://comment.news.163.com/data/boardId/df/新闻ID_1.html,例如http://comment.news.163.com/data/news_guonei8_bbs/df/9IISVTCG0001124J_1.html,这个评论页面有点不同,它返回的不是一个json文件,而是一个Javascript的变量,变量的值就是“=”号后面的内容,它是一个json,因此要更好地观察具体的内容,你应该新建一个文件(例如comment.json),然后把“=”之后,“;”之前的内容中复制出来粘贴到comment.json中,接着用浏览器打开comment.json文件。然后你会看到“热门评论”在’hotPosts’中(内容太长了使用Ctrl+f搜索一下hotPosts),而“精彩盖楼”在’buildPosts’中。评论之间通过”return tiePage.showHotPage(4);“来实现翻页,感觉页面是缓存起来的……一次全部下载完。网易的评论编码好像是UTF-8的,如果乱码那么可以对浏览器选择编码为UTF-8。在实际处理文本内容的时候注意好编码问题。

现在开始分析一下网易新闻评论中各个字段含义,我给出两个例子:

  1. 前面的数字1表示1楼;
  2. f是显示的内容,对应分别为“网易XX网友”,用户ID,用户IP,没有用户ID的就显示“网易XX网友”,连“网易XX网友”都没有的就显示IP地址,我猜的;
  3. v是支持数量;
  4. u不知道是什么粗略看一眼值全部都是’u’;
  5. d是当前评论的新闻id;
  6. t就是发表评论的时间啦;
  7. b就是评论的内容;
  8. a就是表示这个楼是不是最后一层楼的;
  9. p就是上面那个div标签的id;
  10. n怀疑是网易帐号或者用户名;
  11. l不知道是什么;
  12. ip就是ip了。
{
1: {
    f: "网易日本手机网友 <span id=9KUDRCJ8 class=cGray>ip:126.255.*.*:</span>",
    v: "11014",
    u: "u",
    d: "9KUD5BUN00011229",
    t: "2014-02-13 03:34:08",
    b: "媽的,這傻逼幹嘛不索取精液流失費?",
    a: "0",
    p: "9KUDRCJ8",
    n: "chinese_cc@163.com",
    l: "0",
    ip: "126.255.*.*"
}
},

另外一个例子:

{
1: {
    f: "网易山东省济南市手机网友 [<a href=''>逗狗儿玩呵呵</a>]: ",
    d: "9KUD5BUN00011229",
    b: "这么一搞这女的以后还能嫁出去?够阴的。",
    a: "0",
    n: "逗狗儿玩呵呵",
    l: "0",
    tsn: "8058245774",
    ip: "113.128.*.*",
    timg: "http://mimg.126.net/p/butter/1008031648/img/face_big.gif",
    v: "9219",
    u: "u",
    t: "2014-02-13 04:04:49",
    p: "9KUFJMLA",
    tid: "4983565181079566873"
}
},

有没有觉得网易新闻的评论内容中key都很短?而且几乎没有冗余信息。

接下来就是将上述的评论进行格式规范化,假设这个json变量名为js,i为遍历时的下标:

{
    'source' : 'netease',
    'user' : js['hotPosts'][i]['1']['n'],
    'time' : js['hotPosts'][i]['1']['t'], //原格式“%Y-%m-%d %H:%M:%S”,要转换成10位长度的时间戳
    'content' : js['hotPosts'][i]['1']['b']
}

要注意的是,上面的’n’不是一定存在的,因为如果有N楼,那么除了最后一层楼外,从1~N-1楼都是没有’n’标签的。呼,网易新闻的也搞掂了。

3.3 新浪新闻

新浪(评论好像是GBK编码)

新浪新闻的URL规则好复杂,推敲了很久才搞明白。

新闻(非专题类)地址格式:http://news.sina.com.cn/字母c或者w(c表示和中国有关,w表示和中国没有直接关系的世界新闻)/年-月-日/小时分钟(4位数字)及新闻ID的后8位.shtml,例如http://news.sina.com.cn/c/2014-01-19/021929283928.shtml。新浪新闻的地址还有一些地址格式有“变种”,例如:http://news.sina.com.cn/c/sd/2014-01-24/152429336501.shtml,http://news.sina.com.cn/w/p/2014-01-24/154829336676.shtml,还有诸如http://weather.news.sina.com.cn/news/2014/0124/072298232.html和http://mil.news.sina.com.cn/2014-01-24/0839761572.html。

所以综合以上所述,最完整的地址格式应该是:http://[类别.]news.sina.com.cn/一堆可能出现的东西/日期(注意这里的日期格式可能是“年-月-日”也可能是“年/月”)/小时分钟(4位数字)及新闻ID的后8位.shtml或者html

有点蛋碎的感觉,不过没事,这些都是一个正则表达式就搞掂的事。

新浪新闻有一个新闻ID和评论通道,这两个东西都比较麻烦,但又很关键,我这里先说获取的方法,下面就知道用途了。以下是新闻ID获取方法和评论通道获取方法,在新闻详细页面看到找到以下两行:

<meta name="comment" content="kj:2-1-9122947">
<meta name="sudameta" content="comment_channel:kj;comment_id:2-1-9122947">

comment_id同时也是官方所谓的newsid,comment_id的组成是:channelId-1-新闻Id后8位,其中中间的1还不知道是什么意思,comment_channel就是评论通道。

新闻页面获取评论的方法:http://comment5.news.sina.com.cn/page/info?format=格式(可选json,js)&channel=板块(通常是2个字母)&newsid=评论ID(即上面的comment_id)&group=0(默认为0)&compress=1&ie=gbk&oe=gbk&page=第几页(数字越大评论越旧)&page_size=缓存的评论数(并非展示的评论数)&jsvar=requestId_貌似是个随机整数(非常不确定),例如http://comment5.news.sina.com.cn/page/info?format=json&channel=gn&newsid=1-1-29283928&group=0&compress=1&ie=gbk&oe=gbk&page=1&page_size=100&jsvar=requestId_24959748,返回的内容是所有的评论,热门评论在“hot_list”中,关联的新闻信息在“news”中,正常的评论在“cmtlist”中,另外包含一些在“replydict”中的东西,不知道是什么。其中评论数目在“count”的“show”中

对应的所有评论页面地址:http://comment5.news.sina.com.cn/comment/skin/default.html?channel=板块(见上面的解释)&newsid=评论ID,http://comment5.news.sina.com.cn/comment/skin/default.html?channel=gn&newsid=1-1-29283928

最后把得到的评论的格式规范化。假设这个json变量名为js,i为遍历时的下标:

{
    'source' : 'sina',
    'user' : js['hot_list'][i]['nick'],
    'time' : js['hot_list'][i]['time'], //原格式“%Y-%m-%d %H:%M:%S”,要转换为10位时间戳
    'content' : js['hot_list'][i]['content']
}

4 最终格式及补充说明

在新闻格式规范化里面提到了那个格式不是最终的格式,原因就在于实现http://news.reetsee.com(或者我以后直接叫吹水新闻……)功能的时候,当点击了新闻标题时,评论应该是实时获取的(不应该是爬取新闻一样一开始就使用爬虫下载下来),所以我们需要直接拿到评论的具体内容,不能通过评论页面去获取,而应该直接使用获取新闻评论的json接口(就是上面所有的返回数据格式为json的地址),那么就需要我们根据规则直接拼出接口的URL,这些URL中可能会有日期、新闻ID、评论ID、板块ID等不同的变量,所以我们不妨把它直接放到新闻格式规范化的结果中。为什么不直接等点击链接的时候再到新闻页面获取这些ID?因为这样网速会太慢了。

根据实际需求,腾讯、网易、新浪的新闻保存格式如下:

腾讯:

{
    'source'   : 'tencent',
    'date'     : '20140214',
    'newsId'   : '015412',
    'cmtId'    : '1004980094',
    'contents' : {
            'link'   : 'http://news.qq.com/a/20140214/015412.htm',
            'title'  : '哈尔滨一夜清查酒店洗浴等2700余家',
            'passage': '正文内容'
             },
    'comments' : {
            'link' : 'http://coral.qq.com/1004980094',
             }
}

网易:

{
    'source'   : 'netease',
    'date'     : '20140214',
    'newsId'   : '9L2525NG0001124J',
    'cmtId'    : '9L2525NG0001124J',
    'boardId'  : 'news_guonei8_bbs',
    'contents' : {
            'link'    : 'http://news.163.com/14/0214/14/9L2525NG0001124J.html',
            'title'   : '哈尔滨4800余警力一夜清查酒店洗浴等2700余家',
            'passage' : '正文内容'
             },
    'comments' : {
            'link' : 'http://comment.news.163.com/news_guonei8_bbs/9L2525NG0001124J.html',
             },
}

新浪:

{
    'source'    : 'sina',
    'date'      : '20140214',
    'newsId'    : '1-1-29471498',
    'cmtId'     : '1-1-29471498',
    'channelId' : 'gn',
    'contents'  : {
            'link'    : 'http://news.sina.com.cn/c/2014-02-14/142829471498.shtml',
            'title'   : '哈尔滨4800余警力一夜清查2700家酒店洗浴场所',
            'passage' : '正文内容',
              },
    'comments'  : {
            'link' : 'http://comment5.news.sina.com.cn/comment/skin/default.html?channel=gn&newsid=1-1-29471498',
              },
}

上面的格式其实一看就是有问题的,因为扩展性太差了,这也是我第一次设计囿于时间、经验等造成的,各位自己设计的时候就可以设计得更加好。

祝大家端午节节快乐!放假期间还在看这篇博文的人,都是宅男啊¥%%

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2016-06-08

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

32TB Windows 10核心源码与微软内部项目泄露?

今年一直是微软的多事之秋,CIA、NSA的各路工具爆料都和微软密切相关,似乎更劲爆的总在后面:来自国外媒体The Register刚刚的报道,Windows 1...

2764
来自专栏進无尽的文章

基础篇-申请开发者账号

我思故我在,下面就总结下我对 iOS开发者账号的申请中所认为的关键点和所以然,而不单单是网上那些方法步骤哦。 苹果开发者账号分三种。

1461
来自专栏web前端教室

各公司不喜欢招前端新人,但为什么又要去校招呢?

希望十一长假没有让咱们“web前端零基础课0827班”的同学们有过多的懈怠。因为从这几天的作业之中依然可以发现,还是细节方面会有一些问题。

492
来自专栏无原型不设计

给你灵感的23个优秀线框原型图示例

如何在产品初始阶段以最快的方式展示设计思路?我想大多数的UX/UI设计人员都会倾向于快速构建一个线框原型图。这的确是一个非常明智的选择。那么问题来了,设计师如何...

4216
来自专栏别先生

Server Tomcat v7.0 Server at localhost failed to start.

1:这里记录一下这个错误,反正百度一大推,但是很长很长,我感觉这个问题肯定是servlet引起的,因为我遇到的总是如此: ? 2:我的问题如下所示: 1 <se...

2898
来自专栏GopherCoder

『简书API : jianshu 基于 golang (1)』

1634
来自专栏ytkah

神秘代码让iPhone微信闪退的解决方法

  14号晚,很多人的微信朋友圈中出现了这样几句话“听说苹果手机点全文就会闪退”,下方有好几行空白,需要点击“全文”才能看到,但是一旦你是在iPhone手机微信...

3074
来自专栏华章科技

做研究必读:一分钟教你用Excel从统计局抓数据!

首先声明,我并没有学过HTML的语言,也没学过VBA,所以自己解释的逻辑应该是非常容易理解的,保证没有任何编程基础的都能学会。当然前提是你有Excel,没有的话...

773
来自专栏峰会SaaS大佬云集

更新c++学习笔记 第一章

参加了几次笔试,发现有很多c++方面的问题被卡了。从现在开始进攻c++。之后会陆续更新c++学习笔记。

191
来自专栏FreeBuf

走进科学:如何正确的隐藏自己的行踪

大家好!我发现很多新人在讨论 “匿名”,所以我想我该写一篇清晰讲解它的教程,无论你是否能够隐藏自己。 我们也会讨论“隐藏自己”的方法及工具,但先集中注意力去理...

1766

扫码关注云+社区