您的位置:首页 > 编程语言 > Python开发

网易新闻评论爬虫(python+selenium+PhantomJS)

2015-06-29 20:31 801 查看
警示:请勿转载内容

网易新闻评论爬虫设计

废话不多说,我们要爬取这样一个网易的新闻评论页面,页面URL如下:

url = "http://comment.news.163.com/news3_bbs/APLP5TVS00014JB6.html"


这是动态网页,下载网页源代码后是无法直接解析出内容的,我们需要用浏览器内核去解析源代码,直接得到正文。这是一种偷懒的技术,但是可以帮助我们快速获取数据。当然这种方法比较慢,这是最大的缺点。

我们使用的技术是:

selenium和PhantomJS

Linux下的配置详见:http://www.jianshu.com/p/stRYfg

windows下的配置详见:http://www.haiyun.me/archives/989.html

/article/1556285.html

本文的程序基于Windows,我们配置好环境后,源代码如下:

# -*- coding: utf-8 -*-
__author__ = 'Bai Chenjia'
from selenium import webdriver
import re
import codecs

# 对爬虫爬取到的数据进行处理
def handel(content):
raw_content = content.split('\n')
raw_content = list(raw_content)
#print "len", len(raw_content)
if len(raw_content) < 3:
#print "该数组为空"
return "\n"
else:
for temp in raw_content:
# 预处理只保留本层楼的评论,其他楼层的评论去除
if temp == u"回复":
index2 = raw_content.index(temp)
raw_content.pop(index2)
raw_content.pop(index2)
raw_content.pop(index2)
raw_content.pop(index2)
#去除楼数
if temp == "1" or temp == "2" or temp == "3" or temp == "4" or temp == "5" or temp == "6" or temp == "7" or temp == "8":
index1 = raw_content.index(temp)
raw_content.pop(index1-1)
raw_content.pop(index1-1)
raw_content.pop(index1-1)

# 去除【此处隐藏..】这句话
for temp in raw_content:
#print "temp11", temp, type(temp)
if re.match(ur"^[\u5df2\u7ecf\u9690\u85cf].*$", unicode(temp)):
index3 = raw_content.index(temp)
raw_content.pop(index3)

# 从顶中提取数值
for temp in raw_content:
m = re.search(u"\u9876[^\d*?](\d*)\u005d", unicode(temp))
if m:
#print "temp11", temp
index4 = raw_content.index(temp)
raw_content[index4] = m.group(1)

# 从踩中提取数值
for temp in raw_content:
m = re.search(u"\u8e29[^\d*?](\d*)\u005d", unicode(temp))
if m:
#print "temp11", temp
index4 = raw_content.index(temp)
raw_content[index4] = m.group(1)

if len(raw_content) < 6:
return raw_content # 返回
else:
return "\n"

def Crawler(url):
driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)
driver.get(url)
fp = codecs.open("content.txt", 'wb', 'utf-8')

#抓取第一页的数据
contents = driver.find_elements_by_class_name("reply") # 根据class抓取数据
for content in contents:
handel_data = handel(content.text) # 调用处理函数返回一个list
if handel_data == "\n": # 如果为空
continue
else:
fp.write("-----------------------------------------------------\n")
for temp in handel_data:
#print "temp22", temp, type(temp)
fp.write(temp)
fp.write('\n')
print "进入第 1 页"
page = 1
#抓取第二页到尾页的数据
flag = True
while True:
try:
if flag:
driver.find_element_by_link_text("下一页").click() # 找到下一页的连接进入
else:
flag = True
except:
try:
driver.find_element_by_link_text("下一页").click() # 再尝试一次
except:
break
else:
flag = False
continue
else:
page += 1
print "进入第 " + str(page) + " 页"
contents = driver.find_elements_by_class_name("reply")
for content in contents:
handel_data = handel(content.text) # 调用处理函数
if handel_data == "\n": # 如果为空
continue
else:
fp.write("-----------------------------------------------------\n")
for temp in handel_data:
#print "temp22", temp, type(temp)
fp.write(temp)
fp.write('\n')
fp.close()
driver.quit()

if __name__ == "__main__":
url = "http://comment.news.163.com/news3_bbs/APLP5TVS00014JB6.html" # 设定要抓取的网址
Crawler(url)


提示:程序运行可能出现的问题:

程序运行时请关闭所有浏览器,关闭所有下载,尽可能为程序腾出更多的网络资源。

程序可能会在并非完成所有抓取之前就退出,原因应该是代理PhantomJS这个浏览器代理不稳定而导致。因此建议在程序中设定要抓取网页的数量,而并非全部抓取。况且全部抓取所耗费的时间很大。

建议抓取20个网页左右,这样会的到大致300条数据。

程序运行时的Python 的IDE显示:

Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> ================================ RESTART ================================
>>>
进入第 1 页
进入第 2 页
进入第 3 页
进入第 4 页
进入第 5 页
进入第 6 页
进入第 7 页
进入第 8 页
进入第 9 页
进入第 10 页
....


抓取到的数据格式如下:



如有疑问请留言评论。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: