前言:
之前学习了用python爬虫的基本知识,现在计划用爬虫去做一些实际的数据统计功能。由于前段时间演员的诞生带火了几个年轻的实力派演员,想用爬虫程序搜索某论坛中对于某些演员的讨论热度,并按照日期统计每天的讨论量。
这个项目总共分为两步:
1.获取所有帖子的链接:
将最近一个月内的帖子链接保存到数组中
2.从回帖中搜索演员名字:
从数组中打开链接,翻出该链接的所有回帖,在回帖中查找演员的名字
获取所有帖子的链接:
搜索的范围依然是以虎扑影视区为界限。虎扑影视区一天约5000个回帖,一月下来超过15万回帖,作为样本来说也不算小,有一定的参考价值。
完成这一步骤,主要分为以下几步:
1.获取当前日期
2.获取30天前的日期
3.记录从第一页往后翻的所有发帖链接
1.获取当前日期
这里我们用到了datetime模块。使用datetime.datetime.now(),可以获取当前的日期信息以及时间信息。在这个项目中,只需要用到日期信息就好。
2.获取30天前的日期
用datetime模块的优点在于,它还有一个很好用的函数叫做timedelta,可以自行计算时间差。当给定参数days=30时,就会生成30天的时间差,再用当前日期减去delta,可以得到30天前的日期,将该日期保存为startday,即开始进行统计的日期。不然计算时间差需要自行考虑跨年闰年等因素,要通过一个较为复杂的函数才可以完成。
today = datetime.datetime.now()
delta = datetime.timedelta(days=30)
i = "%s" %(today - delta)
startday = i.split(' ')[0]
today = "%s" %today
today = today.split(' ')[0]
在获得开始日期与结束日期后,由于依然需要记录每一天每个人的讨论数,根据这两个日期生成两个字典,分别为actor1_dict与actor2_dict。字典以日期为key,以当日讨论数目作为value,便于每次新增查找记录时更新对应的value值。
strptime, strftime = datetime.datetime.strptime, datetime.datetime.strftime
days = (strptime(today, "%Y-%m-%d") - strptime(startday, "%Y-%m-%d")).days
for i in range(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('.*?(.*?)', 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]* (.*?)
' #找到回帖内容的正则 pattern = re.compile(web_str, re.S) items = re.findall(pattern,content) for item in items: #if '引用' 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至此,我们就利用爬虫知识,成功完成对论坛关键字的频率搜索了。
这只是一个例子,关键字可以任意,这也不只是一个针对演员的诞生而写的程序。将演员名字换成其他词,就可以做到类似“您的年度关键字”这样的结果,根据频率大小来显示文字大小。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
如何解决《域驱动设计自动增量实体密钥》经验,为你挑选了1个好方法。 ... [详细] 如何解决《使用泛型的覆盖方法》经验,为你挑选了1个好方法。 ... [详细] 如何解决《python延迟函数调用》经验,为你挑选了1个好方法。 ... [详细] 如何解决《如何删除滚动RecyclerView上的阴影》经验,为你挑选了1个好方法。 ... [详细] 如何解决《在<URL>中阻止脚本执行.因为文档的框架是沙箱,并且未设置"allow-scripts"权限》经验,为你挑选了4个好方法。 ... [详细] 如何解决《检测ListView何时"向上"或"向下"滚动?WindowsPhone8.1ListView》经验,为你挑选了1个好方法。 ... [详细] 如何解决《Telegrambotapi键盘》经验,为你挑选了1个好方法。 ... [详细] 如何解决《链接是什么:功能"参数"(范围,元素,attrs)?AngularJS》经验,为你挑选了1个好方法。 ... [详细] 如何解决《添加id并使用它的jquery脚本不起作用》经验,为你挑选了0个好方法。 ... [详细] 如何解决《plotlyjs:如何在加载绘图图像后运行我的javascript》经验,为你挑选了0个好方法。 ... [详细] 如何解决《Stata访问元素作为标量或宏的矩阵》经验,为你挑选了1个好方法。 ... [详细] 如何解决《重构Ruby》经验,为你挑选了1个好方法。 ... [详细] 如何解决《java:如何为变量自动生成自定义方法》经验,为你挑选了0个好方法。 ... [详细] 如何解决《自定义URI方案和Skype链接》经验,为你挑选了0个好方法。 ... [详细] 如何解决《有没有办法关闭JIT编译器,这样做会对性能产生影响吗?》经验,为你挑选了1个好方法。 ... [详细] 如何解决《因大小而无法上传文件》经验,为你挑选了0个好方法。 ... [详细] 如何解决《当键盘出现在swift中时,向上滚动UITableView》经验,为你挑选了1个好方法。 ... [详细] 如何解决《Android上的Cordova全屏启动画面仍显示标题栏》经验,为你挑选了2个好方法。 ... [详细] 吐了个 "CAO" !Tags | 热门标签RankList | 热门文章
- 1按一列分组,总结另一列.重复条目(包含特定产品的交易的总交易价值)
- 2如何根据Kubernetes/Docker事件发送警报?
- 3外部共享资源(智能卡)的Java并发模式
- 4测试Jersey应用程序,使用Jersey Injection内置框架(HK2)注入类
- 5Google Developer Console点击启用API会显示"无法加载"错误
- 6是否存在限制解决方案的访问修饰符?
- 7什么会导致Tomcat(v8)具有周期性规律性的CPU峰值
- 8Sonatype Nexus Pro中部署,升级和发布有什么区别?
- 9无法通过CMake找到Eigen3
- 10嵌套RecyclerView的Espresso Matcher
- 11Gemfile在除一个环境之外的所有环境中都需要gem
- 12std :: weak_ptr:lock或shared_ptr构造函数?
- 13无法解析Manifest.permission.ACCESS_FINE_LOCATION
- 14为什么我的BroadcastHashJoin比Spark中的ShuffledHashJoin慢
- 15如果异常不为null,则Nlog输出字符
- 16如何将分割更改为R中的水平分割?
- 17pandas.read_csv中dtype和转换器之间有什么区别?
- 18如何迭代Pandas中的MultiIndex级别?
- 19Matplotlib只是给出错误消息
- 20未找到本机DLL
DevBox开发工具箱 | 专业的在线开发工具网站 京公网安备 11010802040832号 | 京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有