编写Python脚本来获取Google搜索结果的示例


Posted in Python onMay 04, 2015

前一段时间一直在研究如何用python抓取搜索引擎结果,在实现的过程中遇到了很多的问题,我把我遇到的问题都记录下来,希望以后遇到同样问题的童鞋不要再走弯路。

1. 搜索引擎的选取

选择一个好的搜索引擎意味着你能够得到更准确的搜索结果。我用过的搜索引擎有四种:Google、Bing、Baidu、Yahoo!。 作为程序员,我首选Google。但当我看见我最爱的Google返回给我的全是一堆的js代码,根本没我想要的搜索结果。于是我转而投向了Bing的阵营,在用过一段时间后我发现Bing返回的搜索结果对于我的问题来说不太理想。正当我要绝望时,Google拯救了我。原来Google为了照顾那些禁止浏览器使用js的用户,还有另外一种搜索方式,请看下面的搜索URL:

https://www.google.com.hk/search?hl=en&q=hello

hl指定要搜索的语言,q就是你要搜索的关键字。 好了,感谢Google,搜索结果页面包含我要抓取的内容。

PS: 网上很多利用python抓取Google搜索结果还是利用 https://ajax.googleapis.com/ajax/services/search/web... 的方法。需要注意的是这个方法Google已经不再推荐使用了,见 https://developers.google.com/web-search/docs/ 。Google现在提供了Custom Search API, 不过API限制每天100次请求,如果需要更多则只能花钱买。

2. Python抓取并分析网页

利用Python抓取网页很方便,不多说,见代码:

def search(self, queryStr):
   queryStr = urllib2.quote(queryStr)
   url = 'https://www.google.com.hk/search?hl=en&q=%s' % queryStr
   request = urllib2.Request(url)
   response = urllib2.urlopen(request)
   html = response.read()
   results = self.extractSearchResults(html)

第6行的 html 就是我们抓取的搜索结果页面源码。使用过Python的同学会发现,Python同时提供了urllib 和 urllib2两个模块,都是和URL请求相关的模块,不过提供了不同的功能,urllib只可以接收URL,而urllib2可以接受一个Request类的实例来设置URL请求的headers,这意味着你可以伪装你的user agent 等(下面会用到)。

现在我们已经可以用Python抓取网页并保存下来,接下来我们就可以从源码页面中抽取我们想要的搜索结果。Python提供了htmlparser模块,不过用起来相对比较麻烦,这里推荐一个很好用的网页分析包BeautifulSoup,关于BeautifulSoup的用法官网有详细的介绍,这里我不再多说。

利用上面的代码,对于少量的查询还比较OK,但如果要进行上千上万次的查询,上面的方法就不再有效了, Google会检测你请求的来源,如果我们利用机器频繁爬取Google的搜索结果,不多久就Google会block你的IP,并给你返回503 Error页面。这不是我们想要的结果,于是我们还要继续探索

前面提到利用urllib2我们可以设置URL请求的headers,  伪装我们的user agent。简单的说,user agent就是客户端浏览器等应用程序使用的一种特殊的网络协议, 在每次浏览器(邮件客户端/搜索引擎蜘蛛)进行 HTTP 请求时发送到服务器,服务器就知道了用户是使用什么浏览器(邮件客户端/搜索引擎蜘蛛)来访问的。 有时候为了达到一些目的,我们不得不去善意的欺骗服务器告诉它我不是在用机器访问你。

于是,我们的代码就成了下面这个样子:

user_agents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20130406 Firefox/23.0', \
     'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0', \
     'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533+ \
     (KHTML, like Gecko) Element Browser 5.0', \
     'IBM WebExplorer /v0.94', 'Galaxy/1.0 [en] (Mac OS X 10.5.6; U; en)', \
     'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)', \
     'Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.14', \
     'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) \
     Version/6.0 Mobile/10A5355d Safari/8536.25', \
     'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) \
     Chrome/28.0.1468.0 Safari/537.36', \
     'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0; TheWorld)']
 def search(self, queryStr):
   queryStr = urllib2.quote(queryStr)
   url = 'https://www.google.com.hk/search?hl=en&q=%s' % queryStr
   request = urllib2.Request(url)
   index = random.randint(0, 9)
   user_agent = user_agents[index]
   request.add_header('User-agent', user_agent)
   response = urllib2.urlopen(request)
   html = response.read()
   results = self.extractSearchResults(html)

不要被user_agents那个list吓到,那其实就是10个user agent 字符串,这么做是让我们伪装的更好一些,如果你需要更多的user agent 请看这里 UserAgentString。

17-19行表示随机选择一个user agent 字符串,然后用request 的add_header方法伪装一个user agent。

通过伪装user agent能够让我们持续抓取搜索引擎结果,如果这样还不行,那我建议在每两次查询间随机休眠一段时间,这样会影响抓取速度,但是能够让你更持续的抓取结果,如果你有多个IP,那抓取的速度也就上来了。

github上有本文所有源代码,需要的同学可从下面的网址下载:

https://github.com/meibenjin/GoogleSearchCrawler

Python 相关文章推荐
Python中random模块用法实例分析
May 19 Python
完美解决在oj中Python的循环输入问题
Jun 25 Python
Python使用分布式锁的代码演示示例
Jul 30 Python
75条笑死人的知乎神回复,用60行代码就爬完了
May 06 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
Jul 19 Python
Python OpenCV图像指定区域裁剪的实现
Oct 30 Python
python pygame实现滚动横版射击游戏城市之战
Nov 25 Python
将labelme格式数据转化为标准的coco数据集格式方式
Feb 17 Python
PHP基于phpqrcode类库生成二维码过程解析
May 28 Python
python中pathlib模块的基本用法与总结
Aug 17 Python
python基本算法之实现归并排序(Merge sort)
Sep 01 Python
Python3.8.2安装包及安装教程图文详解(附安装包)
Nov 28 Python
编写Python脚本来实现最简单的FTP下载的教程
May 04 #Python
Python下线程之间的共享和释放示例
May 04 #Python
简单介绍Python中利用生成器实现的并发编程
May 04 #Python
简单分析Python中用fork()函数生成的子进程
May 04 #Python
python实现从字典中删除元素的方法
May 04 #Python
Python中利用原始套接字进行网络编程的示例
May 04 #Python
python通过索引遍历列表的方法
May 04 #Python
You might like
php生成随机密码的几种方法
2011/01/17 PHP
PHP缓存技术的使用说明
2011/08/06 PHP
九个你必须知道而且又很好用的php函数和特点
2013/08/08 PHP
php微信公众平台开发(四)回复功能开发
2016/12/06 PHP
Zend Framework使用Zend_Loader组件动态加载文件和类用法详解
2016/12/09 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
PHP使用栈解决约瑟夫环问题算法示例
2017/08/27 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
PDO::_construct讲解
2019/01/27 PHP
js跨域和ajax 跨域问题的实现思路
2009/09/05 Javascript
15 个 JavaScript Web UI 库
2010/05/19 Javascript
javascript判断两个IP地址是否在同一个网段的实现思路
2013/12/13 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
2015/10/29 Javascript
uploadify多文件上传参数设置技巧
2015/11/16 Javascript
BootStrap glyphicons 字体图标实现方法
2016/05/01 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
2016/09/01 Javascript
WebView启动支付宝客户端支付失败的问题小结
2017/01/11 Javascript
原生JS实现幻灯片
2017/02/22 Javascript
详解webpack3编译兼容IE8的正确姿势
2017/12/21 Javascript
jQuery中的$是什么意思及 $. 和 $().的区别
2018/04/20 jQuery
深入理解 ES6中的 Reflect用法
2020/07/18 Javascript
[04:51]TI10典藏宝瓶Ⅱ外观视频展示
2020/08/15 DOTA
本地文件上传到七牛云服务器示例(七牛云存储)
2014/01/11 Python
跟老齐学Python之编写类之一创建实例
2014/10/11 Python
python英语单词测试小程序代码实例
2019/09/09 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
北美Newegg打造的全球尖货海购平台:tt海购
2018/09/28 全球购物
英语演讲稿范文
2014/01/03 职场文书
三八妇女节超市活动方案
2014/08/18 职场文书
党的群众路线教育实践活动教师自我剖析材料
2014/10/09 职场文书
房屋租赁合同协议书范本
2014/10/19 职场文书
《合作意向书》怎么写?
2019/08/20 职场文书
java设计模式--三种工厂模式详解
2021/07/21 Java/Android
关于MySQL临时表为什么可以重名的问题
2022/03/22 MySQL
详解Spring Bean的配置方式与实例化
2022/06/10 Java/Android