百度网页关键字抓取(之前爬虫获取所有帖子的链接:虎扑影视区为界限)
优采云 发布时间: 2022-03-01 21:06百度网页关键字抓取(之前爬虫获取所有帖子的链接:虎扑影视区为界限)
前言:
之前学过python爬虫的使用基础,现在打算用爬虫来做一些实际的数据统计功能。由于前段时间演员的诞生,几位年轻的实力派演员走红。我想用爬虫程序在某个论坛搜索某些演员的讨论,并按日期统计每日讨论量。
这个项目分为两个步骤:
1.获取所有帖子的链接:
将上个月内帖子的链接保存到数组中
2.从回复中搜索演员姓名:
从数组中打开链接,查找该链接的所有回复,在回复中查找演员的姓名
获取所有帖子的链接:
搜索范围仍仅限于虎扑影视领域。虎扑影视区一天回复5000条左右,一个月回复15万多条,作为样本不算太少,有一定的参考价值。
要完成这一步,主要分为以下几个步骤:
1.获取当前日期
2.获取 30 天前的日期
3.记录从第一页返回的所有发帖链接
1.获取当前日期
这里我们使用 datetime 模块。使用 datetime.datetime.now() 获取当前日期和时间信息。在这个项目中,只需要日期信息。
2.获取 30 天前的日期
使用 datetime 模块的好处是它还有一个非常有用的函数叫做 timedelta,它可以自己计算时间差。给定参数days=30时,会产生30天的时间差,然后从当前日期减去delta得到30天前的日期,并将日期保存为startday,即统计时的日期开始。否则,时差的计算需要考虑闰年、闰年等因素,只能通过更复杂的函数来完成。
今天 = datetime.datetime.now()
delta = datetime.timedelta(days=30)
i = "%s" %(今天 - 增量)
startday = i.split(' ')[0]
今天=“%s”%今天
今天 = today.split(' ')[0]
得到开始日期和结束日期后,由于仍然需要记录每个人每天的讨论次数,所以根据这两个日期生成两个字典,分别为actor1_dict和actor2_dict。字典以日期为键,以当天的讨论次数为值,这样每次添加新的搜索记录时,都可以更新对应的值。
strptime, strftime = datetime.datetime.strptime, datetime.datetime.strftime
days = (strptime(today, "%Y-%m-%d") - strptime(startday, "%Y-%m-%d")).days
对于我在范围内(天+1):
temp = strftime(strptime(startday, "%Y-%m-%d") + datetime.timedelta(i), "%Y-%m-%d")
actor1_dict[temp] = 0
actor2_dict[temp] = 0
3.记录从第一页返回的所有发帖链接
如图1所示,所有的发帖时间(精确到分钟)可以通过帖子的顺序排列得到。右键点击查看网页源代码,可以找到当前帖子的链接页面,使用正则表达式抓取链接。
首先是获取30天前的日期,然后抓取第i个页面的源码,用正则表达式匹配,得到网页链接和发帖时间。如图2所示:
比较发帖时间,如果小于30天前,获取发帖链接结束,返回当前获取的链接数组,代码如下
def all_movie_post(ori_url):
i = datetime.datetime.now()
delta = datetime.timedelta(days=30)
i = "%s" %(i - delta)
day = i.split(' ')[0] # 获得30天前的日子
print day
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
post_list = []
for i in range(1,100):
request = urllib2.Request(ori_url + '-{}'.format(i),headers = headers)
response = urllib2.urlopen(request)
content = response.read().decode('utf-8')
pattern = re.compile('.*?<a style="color:#808080;cursor: initial; ">(.*?)', re.S)
items = re.findall(pattern,content)
for item in items:
if item[1] == '2011-09-16':
continue
if item[1] > day: #如果是30天内的帖子,保存
post_list.append('https://bbs.hupu.com' + item[0])
else: #如果已经超过30天了,就直接返回
return post_list
return post_list
函数的参数是链接首页,修改函数中的页码,继续搜索。
从回复中搜索演员姓名:
接下来的步骤也由函数解决。传递给函数的参数包括上一步得到的链接数组,以及你要查询的演员的名字(这个函数可以进一步扩展,演员名字也可以以列表的形式传递,以及上一步生成的字典还可以更多)。
因为虎扑论坛会把一些认可的回复放在前面,也就是重复。如图3所示:
为了避免重复统计,先去掉这些重复,代码如下:
if i == 0:
index = content.find('更多亮了的回帖')
if index >= 0:
content = content[index:]
else:
index = content.find('我要推荐')
content = content[index:]
要删除的规则实际上并不重要,因为每个论坛都有自己的格式。只要在源码中搞清楚怎么写,剩下的操作就可以按照规则进行了。
每个回复的格式大致如图4所示。
使用对应的正则表达式再次匹配,找到每个帖子的每条回复的内容,在内容中搜索演员的名字,即开头的actor_1和actor_2。如果找到,请在相应回复的日期上加上 +1。
最后,返回两个演员的名字出现的频率。按日期记录的字典不需要返回,因为它是一个全局变量。
web_str = '(.*?) .*?.*?[\s]*[\s]*(.*?)<br />' #找到回帖内容的正则
pattern = re.compile(web_str, re.S)
items = re.findall(pattern,content)
for item in items:
#if '<b>引用' in item: #如果引用别人的回帖,则去除引用部分
#try:
#item = item.split('')[1]
#except:
#print item
#print item.decode('utf-8')
if actor_1 in item[1]:
actor1_dict[item[0]] += 1
actor_1_freq += 1
if actor_2 in item[1]:
actor2_dict[item[0]] += 1
actor_2_freq += 1
至此,我们利用爬虫知识成功完成了论坛关键词的频次搜索。
这只是一个例子,关键字可以是任意的,这不仅仅是一个为演员诞生而写的程序。用另一个词替换演员的名字可以做一些类似“你的年度关键词”的事情,文本大小基于频率。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Scripting Home。