Python爬虫开发(四):动态加载页面的解决方案与爬虫代理

0×00 前言

如果读者读过我前面的关于爬虫的文章,应该大概都清楚我们现在可以对一个静态的web页面”为所欲为“了,但是技术的发展总是没有止境的,仅仅是这样对静态页面处理远远不够,要知道现在很多的web页面有意无意为了防止静态爬虫使用ajax技术动态加载页面,这就导致了在面对这些网站的时候,我们前面的技术并不能起到什么很好的效果,所以,我在本系列文章开头就说了会提供动态加载网页的解决方案,在这篇文章里,笔者就在这里提出这个解决方案,用来解决以前我们没有办法的问题。

本人对于Python学习创建了一个小小的学习圈子,为各位提供了一个平台,大家一起来讨论学习Python。欢迎各位到来Python学习群:960410445一起讨论视频分享学习。Python是未来的发展方向,正在挑战我们的分析能力及对世界的认知方式,因此,我们与时俱进,迎接变化,并不断的成长,掌握Python核心技术,才是掌握真正的价值所在。

0×01 动态页面解决方案Selenium+PhantomJS

Python2(或Python3)      本文使用Python2.7.11

Selenium                            自动化web测试解决方案

PhantomJS                         一个没有图形界面的浏览器

0×02 原理回顾对比

讨论:讲selenium自动化测试技术应用于爬虫数据挖掘,其实我也是经历了一段时间的思考,有一些基础的朋友们可能会知道,BeautifulSoup这种完全基于静态的web页面分析是没有办法执行JS的,但是我们在使用web的过程中,基本不可能不用到JS脚本,当时我就想寻找一个JS引擎整合BeautifulSoup,然后计划使用Spidermonkey这个技术,如果需要这么做的话,我们会发现,我们不仅要用BeautifulSoup爬取页面的目标元素,而且还要考虑爬取JS脚本,在执行这些js脚本后,我们还需要再次分析这些脚本返回的数据或者是对HTML页面产生的影响,我觉得这样加大了太多的不确定因素,我们不想花太多的时间放在脚本编写上,既然选用Python,就要发挥它的巨大Pythonic的优势。然后还有一个解决方案就是 Ghost.py,github主页。我想也许我们通过这个方案介绍的不仅仅是爬虫,也可能是一个新世界的大门,所以我还是选择selenium吧,web自动化测试的一整套解决方案。

其实我们从BeautifulSoup的解决方案过度到selenium的方案就是一个思维上的“退步“的过程,从直接HTML解析->分析JS->webkit->索性直接用headless浏览器来操作web页面的selenium。

所以也就是说,我们接下来要讨论的selenium用于爬虫和以前学习的静态页面处理有着本质的区别,可以认为对我们来说是一个全新的技术。

0×03 Quick Start

在这里我们首先可以很负责任的说,通过以下的例子并不会让读者完全掌握selenium的使用,但是通过动手,大家可以了解到selenium是非常好用并且并不输于BeautifulSoup的(也许这两个并不是一个级别并不能比较)。但是可以说BeautifulSoup中的定位元素,在selenium中都可以做到,而且Selenium可以设置等待时间让页面完成加载,或者设置条件让web页面加载出我们所需要的数据然后再获取数据。

下载与安装:

首先我们需要下载要给PhantomJS浏览器from官网

然后安装selenium,使用easy_install或者pip都可以很方便的安装:

1.easy_install selenium

2.pip install selenium

然后我们的第一个目标页面http://pythonscraping.com/pages/javascript/ajaxDemo.html很简单,就是一个存在ajax的情况:页面如下:

Some JavaScript-loaded contentThis is some content that will appear on the page while it's loading. You don't care about scraping this.$.ajax({    type:"GET",    url:"loadedContent.php",    success:function(response){         setTimeout(function(){            $('#content').html(response);        },2000);    }  });functionajax_delay(str){ setTimeout("str",2000);}

我们简单看到这个web页面是使用ajax动态加载数据,GET请求LoadedContent.php然后把结果直接显示在content里。对于这样的方式我们并不需要太深入了解,总之我们只需要知道我们如果使用传统的方式获取,得到的就是上面的静态html而没有loadedContent.php中的内容。

作为selenium的爬虫应用quickstart,我们没必要太深入讲解原理,我们需要把PhantomJS和python脚本放在同一个文件夹下,建立selenium_test.py文件夹

然后输入selenium_test.py中的内容:

#引入selenium中的webdriverfrom selenium import webdriverimporttime#webdriver中的PhantomJS方法可以打开一个我们下载的静默浏览器。#输入executable_path为当前文件夹下的phantomjs.exe以启动浏览器driver =webdriver.PhantomJS(executable_path="phantomjs.exe")#使用浏览器请求页面driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")#加载3秒,等待所有数据加载完毕time.sleep(3)#通过id来定位元素,#.text获取元素的文本数据printdriver.find_element_by_id('content').text#关闭浏览器driver.close()

建议大家先用传统的方法尝试一下这个页面,再使用上面的脚本来执行。观察两个结果有什么不同。当然,我这里明确说明:如果大家真的不想再学习selenium的定位元素,发送数据等操作了,其实也是没什么问题的。通过一个叫page_source的属性,我们完全可以获取当前整个页面的和html,然后再把页面传给BeautifulSoup,这样我们仍然可以使用BeautifulSoup进行解析。 

0×04 Webdriver API

我们发现要使用selenium分析页面,导入的是webdriver,webdriver有很多易用的API:

定位元素,控制浏览器行为,刷新,web元素操作,模拟键盘鼠标事件,获得验证信息,设置等待时间,上传下载文件,调用javascript,窗口截图。

我们写简单的爬虫可能要用得到的就是元素定位和设置等待时间,笔者在这里利用这两个特性再写一个例子供大家理解:

爬取淘宝的商品信息

我们爬取一个淘宝的页面,其实静态很难爬取,淘宝的反爬虫措施相当到位,我们可以先用最简单的方式尝试一下:

importbs4importrequests r = requests.get("https://s.taobao.com/search?q=surface&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.7724922.8452-taobao-item.1&ie=utf8&initiative_id=tbindexz_20160228")data = r.contentsoup = bs4.BeautifulSoup(data)fortaginsoup.tagStack:printtag.encode('gbk','ignore')

我们发现结果:

同时我们发现,通过这种方式获得的html中是没有商品信息的。这样基本所有的静态方式都不可以使用了。

但是selenium的办法是直接操作浏览器所以淘宝并不能挡得住这种数据搜集。

我们先简单看一下能否获取到这个淘宝页面:

from selenium import webdriverimporttimedriver = webdriver.PhantomJS(executable_path="phantomjs.exe")driver.get("https://s.taobao.com/search?q=surface&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.7724922.8452-taobao-item.1&ie=utf8&initiative_id=tbindexz_20160228")time.sleep(7)printdriver.page_source.encode('gbk','ignore')#这个函数获取页面的htmldriver.get_screenshot_as_file("2.jpg")#获取页面截图print"Success To Create the screenshot & gather html"driver.close()

我们还是轻松加愉快的拿到了商品信息,查看文件夹下的截图文件:

2.jpg就是我们截图的文件,打开发现图片显然是没有加载出来的,实际的效果应该是全部图片都加载出来:

放大即可看到高清的网页截图:

这个时候我们有了html可以进行静态解析数据挖掘了。

这里值得提一下的是,selenium注重对单个元素的操作,beautifulsoup注重对html页面的分析和数据分类处理,所以两者结合可以达到非常好的效果,但是大家在使用的过程中就会发现一个问题,使用selenium打开phantomjs的速度有点慢,当然大家还可以用firefox或者是chrome,这些都是selenium支持的。

Have Fun!

其实selenium还有各种各样神奇的功能,比如如果你要自动填写web应用的表单,selenium绝对比什么按键精灵好用的多的很。

0×05 匿名爬虫

有时候比较烦的是,我们使用爬虫来工作,某些情况下IP受限制,这造成了很大的麻烦,如果这个爬虫在服务器端的时候,也许还好,服务器可以提供多个可以选择的IP,但是作为一只家养的爬虫,IP被锁定以后,着实头疼。

当然所谓的匿名爬虫也就是一种以匿名方式请求目标页面,然后获取到页面结果。

0×06 匿名爬虫解决方案(from《webscraping with python》)

Tor+PySocks

Tor的使用https://www.torproject.org/

PySocks设置代理

非selenium的匿名浏览设定使用方法:

importsocksimportsocketfromurllib.requestimporturlopen#假设tor在9999号端口启动socks.set_default_proxy(socks.SOCKS5,'localhost',9999)socket.socket = socks.socksocketprinturlopen('target_web').read()

使用selenium的匿名方式:

fromseleniumimportwebdriver#假定9999端口开启tor服务service_args = ['--proxy=localhost:9999','--proxy-type=socks5', ]driver =webdriver.PhantomJS(executable_path="phantomjs.exe",service_args=service_args)driver.get("target_url")printdriver.page_sourcedriver.close()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容