周四的时候高中同学拜托我写个爬虫程序,用来抓取新浪搜索到的新闻条数,正好我也要学习一下如何自己写一个爬虫,于是便同意了。
一、需求:
同学是学管理的,她的要求是给很多关键词,针对每个关键词去新浪搜索,搜索的要求是按标题检索,同时要对2006年1月至2013年2月的每个月都检索一次,保存检索结果的数目到文件中。比如 关键词是 用友软件,写到文件中应该如下:
用友软件 16 23 67 19 78 ......
文件中每一行是一个关键词对应的检索结果,后面是2006年1月的搜索结果数目,依次直到2013年2月。
为了方便运行,我在她的需求上做出了改进,让文件中的空都用\t隔开便于txt导成excel格式,同时,让输入为从文件输入,每一行为一个关键词,这样只需要写输入文件,运行程序,等待结果输出,最后导入excel即可。
二、实现:
提到爬虫,很多人第一反应就是python,因为python库很多,简单的几个函数就能搞定,代码行数也少。之前我在公司实习的时候见证过JAVA编写的爬虫,不过由于我对JAVA不感冒而且JAVA写爬虫还是要复杂一些,最终我还是选择用python来写。下面来说说步骤:
1、安装python
我的系统是win7,这里推荐一个网址ActivePython http://www.activestate.com/activepython 直接下载安装即可
2、分析网页的html格式
爬虫要抓取的就是html中的数据,自然需要定位到需要抓取的位置,同学给我的要求是抓取搜索结果,在chrome下分析得到的结果如下:
上图中的“ 2005” 就是我需要的数据。
3、编写代码
python抓取网页需要一个很重要的库 urllib2, 至于别人说的beautifulsoup ,pyquery这些库其实并不需要,在定位要抓取的数据时用正则表达式(对应于re库)就可,正则表达式寻找匹配的速度应该来说是最快的。有了这两个库,其他的就是一些逻辑处理,文件读写的操作,没有多少难度。最终的代码如下:
# coding=utf-8import urllib2import re#------------------------------------------------------------------------------def crawl(keyword_name): a = keyword_name; output.write(a+"\t"); for year in range(2006,2013): for month in range(1,13): begintime=str(year)+"-"+"%02d"%month+"-01"; endtime=str(year)+"-"+"%02d"%month+"-31"; print begintime,endtime; userMainUrl="http://search.sina.com.cn/?time=custom&stime="+begintime+"&etime="+endtime+"&c=news&q="+a+"&sort=time&range=title"; print userMainUrl; req = urllib2.Request(userMainUrl); resp = urllib2.urlopen(req); respHtml = resp.read(); #print "respHtml=",respHtml; # you should see the ouput html #<div class="l">我们为您搜索到2,005条新闻结果</div> urlpat = re.compile(r'<div class="l">(.*?)</div>'); match = urlpat.findall(respHtml); for numstr in match: searchnum = numstr[14:-10]; print "searchnum=",searchnum; output.write(searchnum+"\t"); year=2013 for month in range(1,3): begintime=str(year)+"-"+"%02d"%month+"-01"; endtime=str(year)+"-"+"%02d"%month+"-31"; print begintime,endtime; userMainUrl="http://search.sina.com.cn/?time=custom&stime="+begintime+"&etime="+endtime+"&c=news&q="+a+"&sort=time&range=title"; print userMainUrl; req = urllib2.Request(userMainUrl); resp = urllib2.urlopen(req); respHtml = resp.read(); #print "respHtml=",respHtml; # you should see the ouput html #<div class="l">我们为您搜索到2,005条新闻结果</div> urlpat = re.compile(r'<div class="l">(.*?)</div>'); match = urlpat.findall(respHtml); for numstr in match: searchnum = numstr[14:-10]; print "searchnum=",searchnum; output.write(searchnum+"\t"); output.write("\r\n");###############################################################################if __name__=="__main__": with open('input.txt', 'r') as fp: output = open('output.txt', 'a'); for line in fp: keyword = line.strip(); crawl(keyword); output.close();
这里输入文件为input.txt, 注意python的编码有时存在问题,所以input.txt的编码格式要保存为GB2312(在notepad++下选择ANSI编码即可)
input.txt文件:
用友软件中国证券
output.txt文件:
用友软件 33 19 5 2 3 8 3 5 11 3 5 13 3 2,005 34 16 7 17 2,005 2,005 15 15 5 12 12 24 26 17 17 10 5 30 15 25 14 22 1 10 25 17 17 19 3 2,005 25 8 11 19 14 4 20 12 5 38 7 10 12 5 16 10 7 7 17 12 15 6 4 14 20 23 26 11 1 4 18 11 7 5 20 8 5 7 38 28 17 7 中国证券 52 61 9,224 89 71 100 107 102 129 76 180 183 39 28 25 8,073 34 86 65 72 98 73 88 80 102 133 160 170 103 182 188 150 9,224 186 136 169 129 154 123 28 31 37 46 48 54 40 44 42 483,224 27 56 9,224 30 21 16 12 38 27 61 51 22 18 23 25 28 51 9,224 50 74 70 127 80 32 57 62 43 43 101 72 103 83 60 134 75 43 37
总结:写了这么一个程序,让我对python又有了更进一步的了解,如今很多数据都需要借助于爬虫这个工具,强大的python外加正则表达式基本能满足任何的需要。最后感想老大的指点,相信我的那位高中同学会感到满意的。
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow