- 简介
- 任务简述
- 实现过程
简介
我最近在看关于计算机的一些书籍,发现了这个电子书清单:计算机开放电子书汇总, 和大家分享一下. 我在下载其中的书籍时被导向了这个很好的计算机电子书网站KanCloud看云,里面有非常多的实用的编程方面的电子书,很多是该网站自己用html生成的,格式多样,包括pdf,epub,mobi. 在此表示感谢,强烈推荐.
于是,我准备用之前的静态网页爬虫来批量下载,发现书籍的链接是javascript生成的,而且难以解析(我还会写一篇抓取可以解析js的网站的博客). 这时我们可以用selenium来模拟浏览器的动作,例如下拉或者点击button之类的. 然后在看云网站里模拟下载.
要得到一个可以稳健运行的爬虫, 需要考虑一些细节问题, 因此分两篇来说,本篇先给出一个示例,了解工作的过程.
任务简述
进入网站后,看云网站界面如下图所示:
要下载全部电子书,我们需要抓取70个page, 每个page有12本书,每本书有一个单独的页面,而且有的书籍不提供下载,有的可以下载多种格式.
因此, 我们的任务如下:
1. 解析首页,得到最大页码
2. 解析单个页面,得到该页书籍链接列表
3. 进入书籍页面
* 判断是否可以下载
* 可以下载则下载所有格式的书籍
其次, 为了获得爬虫的鲁棒性, 我们要保证每次网页都加载成功,文件下载都完成了,在下面的内容里我会一步步介绍.
实现过程
Selenium可以模拟打开浏览器,在这之前我们要下载浏览器的驱动器.在本文里,我们使用chrome浏览器,Firefox也是常用的浏览器,使用步骤差不多,不再赘述.
Selenium
的安装:
sudo pip install selenium
然后下载chrome的webdriver, 直接保存在本地,例如/usr/bin
, 然后设置selenium的基本设置
import re#正则表达式
import random#随机选择
import subprocess# 执行bash命令
from multiprocessing import Pool#建立线程池,并行爬取加快速度
from selenium import webdriver# set chromedriver path and download path
chromeOptions = webdriver.ChromeOptions()dl_path="~/Downloads/KanCloud"#设置下载路径
chromedriver="/usr/bin/chromedriver"#修改为你的chromedriver路径prefs = {"download.default_directory" : dl_path}
chromeOptions.add_experimental_option("prefs",prefs)#可以为webdriver设置代理,自动获得代理IP地址下面会解释,这里注释掉
#PROXY='1.82.216.134:80'
#chromeOptions.add_argument('--proxy-server=%s' % PROXY)# url_start='http://www.kancloud.cn/explore/top'#建立一个webdriver对象
driver = webdriver.Chrome(chrome_options=chromeOptions)
driver.get('http://www.kancloud.cn/digest/ios-mac-study')#用chrome打开这个网页
运行上面的代码就可以打开一个chrome标签页了, 如下图所示:
点击下载
按钮,我们看到有三个可以下载的选项PDF, epub, mobi
. 要模拟click action, 我们需要得到该element的位置. 这时我们可以借助chrome的inspect功能, 快捷键是Ctrl+shift+I
, 或者把鼠标悬浮在下载
上,点击右键选择inspect,效果如下图:
选中右边高亮的代码,右键->copy->copy xpath,即可得到该element的xpath
//*[@id="manualDownload"]/span/b
再利用webdriver本身的xpath搜索功能得到该element,并模拟click操作
driver.find_element_by_xpath('//*[@id="manualDownload"]/span/b').click()
运行上面这句话,我们看到网站的确响应了,出现了支持下载的3种电子书格式. 这一步的点击下载
按钮是必须的,否则直接click epub会报element not visible的错误. 接下来我们示范下载epub, 将鼠标悬浮在epub
上,右键查看,即可得到下载epub的xpath,同上操作
driver.find_element_by_xpath('//*[@id="manualDownload"]/div/div/ul/li[2]/a').click()
这样我们就可以把这个epub电子书下载到我们指定的路径了.
Selenium的基本应用就是这样了. 它还有一些其它的定位element的方法和模拟操作的功能, 例如常用的把网页往下拖, 因为有的网站会根据用户下拉的情况来渲染网页,越往下拉显示的内容越多. 具体请看selenium的官方文档.
我们将以上过程针对每一个page每一本书执行,即可爬取全站的书籍了,前提是你的网速足够快,运气足够好. 这是因为在连续爬取时,会出现一些异常,例如
1. webdriver打开网页会失败
2. 下载还没完成就打开下一个网页,造成webdriver负担过大从而加载网页失败
3. 网站可能会根据IP地址反爬虫
在下一篇中我们会解决以上问题,并用多进程加快速度(webdriver打开网页实在太慢).