Python网络爬虫实战---斗图表情包
人生苦短,我用python.废话不多说,直接上干货。
环境:mac os 10.12.1 , python 2.7
库:selenium
IDE:PyCharm
javascript动态网页抓取
做过网络爬虫的朋友应该都知道,我们做爬虫粗略的将网页分为动态网页和静态网页这两类。这里的动态和静态是指我们打开一个url如果能直接得到该网页的所有内容则为静态网页,如果打开一个url我们得到的只是一串javascript代码,网页内容还需要执行javascript代码才能得到的称为动态网页。静态网页很容易解决,直接解析就好了;而动态网页就会复杂很多一般也分为两种情况第一手动去执行javascript中的操作,这种难度太大了不适合我们这样的小白,第二种就是调用浏览器去打开网页让浏览器去执行javascript代码加载所有的网页内容。这里我们采用第二种方案,调用模拟器去打开动态网页。
selenium
Selenium是一个用于Web应用程序测试的工具,我们就是借助这个工具来操作浏览器实现第二种方案。具体介绍可参考百度百科:https://baike.baidu.com/item/Selenium/18266?fr=aladdin。
环境搭建
安装selenium
执行命令:pip install selenium
提示:pip是一款包管理工具没安装的小伙伴快去安装吧,用pip安装python模块简直不能太爽。
安装完成后打开终端,输入python 回车,进入python
输入:from selenium import webdriver 回车。未报错则成功,失败则重新安装selenium模块。
输入:web = webdriver.Firefox() 回车。打开浏览器
正常情况下会打开一个这样的Firefox
地址栏是黄色条纹,上面有个小机器人,如果出现这个错误selenium.common.exceptions.WebDriverException: Message: 'firefoxdriver' executable needs to be in PATH.没关系这个只是没安装驱动安装下驱动就好了。
mac版firefox驱动: http://download.csdn.net/download/qq_34122135/10203884
官网firefox驱动:点击打开链接
mac:下载完驱动,解压得到geckodriver,然后把文件移到/usr/local/bin下面,并给x执行权限即可。
linux:下载完驱动,解压得到geckodriver,然后把文件移到/usr/bin下面,并给x执行权限即可。
安装完驱动,然后我们测试一下用python代码控制浏览器打开百度首页。
from selenium import webdriver wb = webdriver.Firefox() wb.get("http://www.baidu.com") # 打印网页源码 print wb.page_source
我们可以看到启动一个带小机器人的firefox,并且打开了百度首页,控制台也输出了百度首页的所有源码
到这里我们的基本环境就已经配置好了,接下来我们开始抓取表情包。
实战
百度作为国内最强大的搜索引擎,不用它简直暴殄天物,我们使用百度图片搜索的功能来实现我们的表情包爬虫。
我们先打开百度图片搜索“表情包”
记得在网页右上角把瀑布流改为传统模式。好了,这些图片就是我们想要的表情包了,接下来我们只要分析一下网页结构按规则过滤就可以得到图片链接了。注意下面还有个页码指示器,如果只抓取一页的结果未免也太low了,我们要想抓几页抓几页!所以待会这一部分的结构也得分析清楚。
结构分析
我们用firefox自带的工具查看即可,鼠标放在网页上点击右键弹出菜单,选择查看元素就可以很清晰的看到文档结构了,简直真神器(技术宅都用Firefox看来是有道理的)。
我们发现所有表情包都处在一个id叫wrapper的div标签里面,每一个表情包都是一个img标签。好了掌握这些信息就足够清洗出来我们需要的数据了。
接下来再分析下页码指示器的结构
我们同样可以发现页码指示器处于一个id叫page的div标签里,每一个页码是一个class为pc的span标签。掌握这些数据已经足够我们清洗出来所需要的数据了。
好了,环境已经配置好了,文档结构也分析完了接下来就是写代码。
下载图片的模块
# -*- coding=utf-8 -*- """ @version: @author: zcy @Mail: zcy_2018@163.com @file: download.py @time: 2018/1/13 上午11:42 """ import urllib # path为要保存图片的文件夹 def downloadByHttp(url,path="/Users/mac/Pictures/spiderImg/"): # 截取文件名,避免文件名过长只截取最后20位 fileName = url.split("/")[-1:][0][-20:] # 获取文件参数 conn = urllib.urlopen(url) # 获取文件后缀名 sub = conn.headers['Content-Type'].split("/")[-1:][0] print 'sss:',sub conn.close() # 如果这个超链接不包含后缀名,则加上一个后缀名 if fileName.find(".") == -1: fileName = fileName+sub print fileName print "downloading with urllib" urllib.urlretrieve(url, path+fileName)ImgSpider
# -*- coding=utf-8 -*- """ @version: @author: zcy @Mail: zcy_2018@163.com @file: te.py @time: 2018/1/13 上午11:17 """ from selenium import webdriver from NetUtil import download class ImgSpider(object): # wd 搜索的关键字,maxPage最大下载的页数 def __init__(self, wd="", maxPage = 5): # 百度图片搜索的http请求 self.url = "https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word="+wd # 打开火狐浏览器 self.wb = webdriver.Firefox() # 设置最大下载你页数 self.deep = maxPage self.start = 1 # 打开第一页 def first(self): # 打开url获取第一页结果 self.wb.get(self.url) # 解析网页 self.parse() # 读取下一页 self.onNext() # 递归读取下一页,直到条件不满足 def onNext(self): # 当前页码加1 self.start += 1 # 解析网页 self.parse() # 通过xpath方法匹配页码指示器 element = self.wb.find_element_by_xpath("//div[@id='page']") for el in element.find_elements_by_xpath(".//span[@class='pc']"): # 获取页码 str = el.text num = int(str) # 比较页码,不满足条件则关闭程序 if num > self.deep: self.close() # 继续执行下一页操作 if num == self.start: el.click() self.onNext() # 解析下载图片 def parse(self): # 通过xpath匹配当前网页的所有图片的最上层节点 imgs = self.wb.find_element_by_xpath('''//div[@id="wrapper"]''') i = 0 # 匹配所有的图片节点,遍历下载 for img in imgs.find_elements_by_xpath(".//img"): i = i + 1 # 获取img标签的连接 url = img.get_attribute("src") print url # 给下载模块下载图片 download.downloadByHttp(url) #关闭爬虫 def close(self): self.wb.quit() exit() #开始抓取数据 关键字 和 最大页数 spider = ImgSpider("表情包", 5) spider.first()
大功告成,接下来我们运行下ImgSpider,下载了两页的表情包,妈妈再也不用担心斗图了
最后附上完整源码: