作者在Nature 2018关键词这个帖子里面所用到的数据就是用python写了一个简单的爬虫程序,几分钟内就获取了Nature主刊在2018年所刊登的所有文章信息。因为Nature期刊网页是比较开放的,所有你看到的网页内容基本都可以在网页的html文件里面获得,也就是所谓的静态网页。但是有些网站,比如GoEuro,AirBnB这种商业网站的网页就没有那么简单了,你在浏览器里面看到的内容在当前网页的html文件里面找不到。这是因为网站在跟你捉迷藏!使用了大量的JavaScript内容!对付这样的网站,就不能用简单的爬虫方法(
from urllib.request import urlopen
)了,高级一点的方法就是利用Selenium来模拟人类操作(比如单击、登录、翻页等)浏览器来获取网页内容!
Selenium
Selenium本来是为测试网页而设计的,当然也可以用于爬虫了。它的安装还有使用方法,在其官网上有详细说明,下面只挑几个重点列举。简单的入门也可以参考这篇博客+视频
这里假设目标机器上已经有了python的相关环境
安装Selenium
pip install Selenium
Web Driver
既然要模拟人类操作浏览器,那么这个过程肯定是基于浏览器这个软件了,所以需要对应浏览器的驱动(Driver)内核程序,根据官网的说明,Selenium目前支持四种浏览器
我是Mac系统,当然是用Safari浏览器了,点开相应的driver链接发现,新版Mac系统(Safari 10 on OS X El Capitan and macOS Sierra)已经提供了原生的Safari WebDriver程序了,所在路径为
/usr/bin/safaridriver
。所以对于Mac用户,这一步可以跳过了!现在就可以直接上一小段代码来个hello world了
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Safari()
driver.get("https://www.modernfig.cn")
driver.find_element_by_link_text("Team").click()
driver.find_element_by_link_text("Blog").click()
driver.close()
注意: 在你直接用的时候回提示这样的错误:
SessionNotCreatedException: Message: Could not create a session: You must enable the 'Allow Remote Automation' option in Safari's Develop menu to control Safari via WebDriver.
解决方法就是:根据这个提示在你的Safari浏览器的Develop菜单下面找到Allow Remote Automation
这个菜单按钮(倒数第三个)单击即可!
运行这段代码的效果就是浏览器会自动打开www.modernfig.cn
(🤔这是我用sphinx做的个人网站😎),然后完成代码里面的任务(两个单击操作分别打开Team页面和Blog页面)就自动关闭!
小白初尝
问题来了,人类对浏览器的操作怎么用python代码来表达呢?这个问题对于熟悉爬虫的程序猿或者爱好者来说,不是个问题,因为他们已经记住了怎么写这些代码!对于初学者,有个简单的方法,就是跟word里面录制宏的功能一样,也可以对浏览器的操作进行录制,保存为python代码。
浏览器的操作录制需要借助Chrome浏览器了,因为它有一个很棒的插件叫Katalon Recorder ,可以进行这样的骚操作!为什么Safari没有?Mac在2018年11月升级之后,对Safari的插件管理更严格了,彻底禁止了未知开发者的插件了,而且只在App Store里面开放Safari的插件下载!
录制完成后,导出为python代码,很长一段,都是固定格式的,我们关注的就是类似下面的这段代码:首先打开了www.modernfig.cn
然后进行了两次点击操作
driver.get("https://www.modernfig.cn")
driver.find_element_by_link_text("Team").click()
driver.find_element_by_link_text("Blog").click()
注意:上面的简单的演示过程中程序都会自动打开Safari浏览器界面,然后模拟人的点击操作,但是我们在批量爬去内容的时候或许不希望界面显示出来,让它在后台运行即可!这个就需要用的
--handless
选项了,但是Selenium目前好像不支持Safari的handless选项,因此如果想后台运行selenium程序代码,需要用chrome浏览器。关于Chrome浏览器的web driver,下载然后拷贝到/usr/local/bin
目录下即可. 设置后台运行的代码如下:
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless") # define headless
driver = webdriver.Chrome(chrome_options=chrome_options)
获取网页
经过上面的几个步骤,现在已经能让程序控制你的浏览器了。接下来就到正事儿了:获取网页内容 driver.page_source
,还可以保存网页截图 driver.get_screenshot_as_file("skyscanner.png")
!!!
from urllib.request import urlopen
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("--headless") # define headless
driver = webdriver.Chrome(options=chrome_options)
url='https://www.skyscanner.net/transport/flights/fran/hamb/181109/181116/?adults=1&children=0&adultsv2=1&childrenv2=&infants=0&cabinclass=economy&rtn=1&preferdirects=false&outboundaltsenabled=false&inboundaltsenabled=false&ref=home#results'
driver.get(url)
html = driver.page_source # 获取html
driver.get_screenshot_as_file("skyscanner.png") #保存网页截图
driver.close()
获取网页以后,对网页的解析和提取信息,就跟简单爬虫教程里面的一样啦,用BeautifulSoup解析就行!
好像goeuro和skyscanner这两个网站都设置了反爬虫程序,有机器人验证!目前还不知怎么破,后面再补充吧!不过booking和Airbnb可以愉快的爬虫!旅行酒店比价问题基本解决了!接下来找一个方便找机票和火车票信息的网站就完美了!
Google Flight
Google Flight 查询机票价格信息还是个不错的选择,没有设置那么强的验证限制。不过最好是设置几十秒的间隔时间,防止被查封!本来Google Flights提供开放的API的,但是2018年四月份关闭了这个服务。
先别高兴太早:打开Google Flights搜索结果的网页,发现浏览器显示源码里面并没有价格等信息,因为你看到的网页是经过JavaScript允许之后的,不是静态网页!!!这就是前面说的网站在跟你玩捉迷藏!用命令 html = driver.page_source
获取的html与浏览器源码显示的一毛一样,缺失了很多信息,不是页面显示的信息!怎么办?
用下面这个命令可以获取内部数据:
elem = driver.find_element_by_xpath("//*")
source_code = elem.get_attribute("outerHTML")
对于刚入门的我来说,未解决这个问题,找了很多地方,最后发现还是google搜索强大,直接用英文搜索会出来更多有价值的东西!最终在全球最活跃的程序猿论坛 stack overflow找到了答案!这个操作简直不要太给力!😎
至此,基本上日常生活中的爬虫任务解决了!