首页 > 代码库 > python爬虫之采集360搜索的联想词

python爬虫之采集360搜索的联想词

有个视频专门讲过这个爬虫,但是太罗嗦了,顺便整理下,而且到现在,360也不傻,已经进化了,采用原来的方式,多少有点bug,这个后面会说。正题如下:

语言:python2.7.6

模块:urllib,urllib2,re,time

目标:输入任意词,抓到其联想词

版本:w1

原理:在360搜索主页:http://www.so.com/,当你输入”科技“时,搜索框会列出相应的联想词或者短语,我们就是要得到这些联想词,那就要爬360的搜索引擎了。在输入关键词之前,我们在主页右键,”审查元素“——”Network“——”Name“,输入之后,下面会出现相应的超链接,我们只观察”Headers“”Priview“,”Headers“下我们可以看到”“Request URL”和头信息(主机,代理之类的),“Priview”中看到一个我输入的例子:

suggest_so({"query":"科技 ","result":[{"word":"科技美学"},{"word":"科技苑"},{"word":"科技部"},{"word":"科技管理研究"},{"word":"科技少女喵","obdata":"{\"t\":\"video\",\"d\":[2,\"http:\/\/p0.qhimg.com\/d\/dy_acba03288ce64a69a324a94921324cb6.jpg\",\"\u9ad8\u79d1\u6280\u5c11\u5973\u55b5\",\"http:\/\/www.360kan.com\/tv\/Q4pwcH3lRG4lNn.html\",3,12]}"},{"word":"科技日报"},{"word":"科技发展利大还是弊大"},{"word":"科技超能王"},{"word":"科技网"},{"word":"科技进步与对策"}],"version":"a"});

很明显,我们只要抓到里面的词即可,忘了交代,在Request URL中,有一个链接:http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word=%E7%A7%91%E6%8A%80%20,我们输入很多次发现,变得只是“%E7%A7%91%E6%8A%80%20”部分,也就是说前面的部分不变,我们可以直接拿来用,后面的部分随着输入的关键词不同而变化,这是一种URL编码,可以用urllb.quote()方法实现。

操作:1.加头信息,读取网页,相关方法:urllib2.Request(),urllib2.urlopen(),urllib2,urlopen().read()

     2.正则匹配:方法:re模块的相关用法,各抒己见。。

代码如下:

#coding:utf-8
import urllib
import urllib2
import re
import time

gjc = urllib.quote("科技")
url = "http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word="+gjc
print url
req = urllib2.Request(url)
html = urllib2.urlopen(req).read()
unicodePage = html.decode("utf-8") 
#正则表达式,findall方法返回一个列表
ss = re.findall('"word":\"(.*?)\"',unicodePage)
for item in ss:
    print item
结果:

如果不加unicodePage = html.decode("utf-8") ,返回值会穿插一些乱码,下面我们验证下,我们做的对不对,打开360搜索,输入“科技”,结果如下:

大家不要纠结,第一个和第二个关联词的顺序,我第二次请求的时候就变成了上图的结果,再一次请求,又变回来了,可能是360在变吧,大家可以用其他关键词试试。

好,大体框架已经实现,这是个最初版本,还不能完全无限制使用,我们要做的是畅通无阻,那么存在什么问题呢?

题:1.多次请求会出现一个错误,大概代号为1005,意思百度了下,好像是说网站会限制非人为的请求,那我们要伪装成用户正常打开网站的行为,我们要用到头信息(这是我自己习惯叫的,我们采用“Request Headers”里面的信息即可

2.请求过快也可能被屏蔽,所以要在每一次请求之后让爬虫休息一下,这就是time.sleep()的作用

3.即使这样,也有被屏蔽的可能,必杀技:使用ip代理服务器,百度ip代理,一大堆免费的,方法:见urllib2 api example

优化的代码如下:

#coding:utf-8
#---------------------
#   程序:爬虫采集360搜索关联词
#   语言:python2.7
#   版本:w1
#   时间:2014-06-14
#   作者:wxx
#---------------------
import urllib
import urllib2
import re
import time
from random import choice

#ip代理列表
iplist = ["14.29.117.36:80","222.66.115.229:80","59.46.72.245:8080"]
ip = choice(iplist)
#print ip
#关键词列表,顺序搜索
list = ["集团","科技","python"]
for m in list:
    #quote将m转变成URL编码
    gjc = urllib.quote(m)

    url = "http://sug.so.360.cn/suggest?callback=suggest_so&encodein=utf-8&encodeout=utf-8&format=json&fields=word,obdata&word="+gjc
    #头信息
    headers = {
                "GET":url,
                "Host":"sug.so.360.cn",
                "Referer":"http://www.so.com/",
                "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 QIHU 360SE"
                }
    #使用IP代理服务器
    proxy_handler = urllib2.ProxyHandler({'http': 'http://'+ip})
    opener = urllib2.build_opener(proxy_handler)
    urllib2.install_opener(opener)


    req = urllib2.Request(url)
    for key in headers:
        req.add_header(key,headers[key])
    html = urllib2.urlopen(req).read()
    #将其他编码变成unicode编码
    unicodePage = html.decode("utf-8") 
    #正则表达式,findall方法返回一个列表
    ss = re.findall('"word":\"(.*?)\"',unicodePage)
    for item in ss:
        print item
    #休眠2秒
    time.sleep(2)

结果截图:

下一版本的优化考虑:

1.让用户自助输入关键i词,不要事先定义关键词列表

2.按回车进行下一个关键词输入

3.输出结果保存txt文本

4.用户输入exit,程序退出