爬虫目标:
获取https://www.factual.com/data/t/hotels-us中的酒店数据,并生成标准xls表格
网页特征:
1.有人机验证码
2.数据动态加载
3.页面数据使用链接后添加#offset=xx(数据偏移)加载数据
源码git地址(仅供参考学习):https://github.com/EthanXzhang/HotelDataCrawler
构思阶段:
常规爬虫使用beautifulsoup进行静态页面扒取。
经过检视页面静态代码,编写完成了静态页面的控件定位与内容获取。
同时使用xlrd和xlwt将数据写入表格。
运行后,发现无法获取页面数据。通过打印html信息,发现容器内容未加载。
使用selenium自动化测试工具:
由于beautifulsoup为伪造浏览器登陆,比较难以解决动态加载页面的问题。
综合考虑,在访问页面部分,改用了selenium的webdriver进行浏览器访问。
webdriver使用本机firefox浏览器。webdriver支持多种浏览器(Chrome、Firefox、IE等),对新版浏览器的支持可能不太好。这里留下git的webdriver下载地址:https://github.com/mozilla/geckodriver/releases
程序开发:
由于使用beautifulsoap时已基本编写完了页面控件定位与内容获取的函数,因此为了尽量少更改原有代码,加快开发进度,因此使用了webdriver的方法,生成html,传给beautifulsoap解析。
browser = webdriver.Firefox(executable_path="geckodriver.exe")
...
return browser.page_source.encode('gbk', 'ignore')
return返回webdriver加载完的html静态页面。
webdriver可以设置访问超时时间,否则webdriver会一直等待网页加载,直到加载完成才执行下一段代码。对于一些国外站点,webdriver会等待很长时间,但refresh刷新方法再次访问同一网页将会比较迅速。
视个人情况,超时时间可以抛出异常,具体请查阅其他详细资料,这里不过多展开。
难点解决:
1.获取验证码验证cookie
检视了原网页,发现,进行了一次验证码验证后,关闭浏览器前再次访问页面,无需验证码。
基本可以判断,验证码验证存储在了cookies中,并随着浏览器关闭而失效。
在Firefox浏览器下安装插件cookiemanager。通过验证码验证前和验证后的cookie改变状态,定位到了记录验证状态的cookie为
domain=www.factual.com name=_www_session expiry=0
获取该cookie的value值。
2.webdriver访问加载cookie
out={ u'domain':u'www.factual.com',u'expiry':2147385600, u'httpOnly':True ,u'secure': False ,u'name':u'_www_session',
u'value':u'ekRNZHU2YkxUK3JiNTlJcEhWWGs5czBHY2ZiZHlITnUwOU1yWmp2dXJiVllVRXJLcjBUQjdycERGYzM3SzRnek5lY01pbkI5eWNjUnFQQy9FbUFkUDIxcG9qWFBnd3lldktoaDVGUFgwYk9ocy93NDRvVi91S0VsTS91aDRYZ1dVbEw4Um9VMjNHVlBNUjcxS1pmcVR2R1c1djFiWEJtdStzcnUydDVmdnVFNjhneTBlUkRxUjhzcGZvMjdLNDBtWjhqeWJUa3FqVGYwZXc2eEZGTUIrMHRzdjNnVHhWdVlMQmZZaDdmRTR5WFlNR3VVcFUxTlI5VXpUUFg3dkt6MnVoMHVhWTd4Y3hvWStiMVJDQ2p2NWtBVFBwc1lTd1FuYXlwTC9mM09FSFZPSGZYSGxCZjY5eGtEbmxyY1N6c01FMU5yWXd5RUR4QllxOVBFcWUzMlZkOTQ0ekVFbysvd2JnVEp3OFFzNUNVPS0tODl6N0hkYXpMS3FtbUw1VzJsditvUT09--bdc3c540306fc56cc4a7fdd92ce8541170797a9d' , u'path':u'/'}
browser.add_cookie(out)
out为字典写入的cookie。
由于webdriver的特性,添加cookie必须在get(url)访问之后,才能添加。
在get(url)访问往前前使用add_cookie方法,是无法添加cookie的。
这里建议先使用get(url)访问一次页面,delet_all_cookie删除cookie,然后再使用add_cookie加载你需要cookie。
由于这里仅有一个cookie影响验证,因此只需要add这个cookie就可以跳过验证。
在添加了cookie后,使用
browser.refresh()
刷新一次页面,即可跳过验证。
3.循环读取数据
在main函数中,添加offset来往后遍历所有数据页面。每次页面读取完成,使用xlwt写入xls缓存,并在循环结束后生成xls文档。
由于是简单的循环与xls写入操作,这里就不过多复述了。代码可以进入git查看。
4.关于xlwt与xlrd
xlwt不能改写原有文档的数据,每次生成文档会覆盖原有文档(文件覆盖,不是表格数据覆盖)。
xlrd仅能读取数据,不能进行写入或者其他的操作。
workbook = xlwt.Workbook()
...
workbook.save('HotalData.xls')
save操作完成文件生成,可以填写文件路径,默认工程目录。