龙空技术网

想学Python爬虫,我教你控制浏览器拿到数据,这才是最好的入门

外星人玩Python 105

前言:

此时同学们对“python网页爬数据”大概比较关注,同学们都需要知道一些“python网页爬数据”的相关资讯。那么小编在网摘上收集了一些对于“python网页爬数据””的相关知识,希望各位老铁们能喜欢,姐妹们快快来了解一下吧!




此系列文章收录在公众号中:数据大宇宙 > py爬虫 > Selenium

转发本文并私信我"python",即可获得Python资料以及更多系列文章(持续更新的)

作为"数据玩家",如果手头上没有数据怎么办?当然是用代码让程序自动化采集数据,但是现在"爬虫"不是那么容易,其中最困难的即是突破网站各种反爬机制。本系列将全面讲解 Python 中一个非常成熟的库 —— selenium,并教会你如何使用它爬取网络上所需的数据

自动化爬虫虽然方便,但希望大家能顾及网站服务器的承受能力,不要高频率访问网站。并且千万不要采集敏感数据!!否则很容易"从入门到入狱"

本系列大部分案例同时采用 selenium 与 pyppeteer 库讲解,并且有 Python 和 C# 2门语言的实现文章,详细请到公众号目录中找到。


拿到数据也要会处理和分析数据,我的 pandas 专栏就是最好的入门到高级的教程



前言

学习任何一个库,必须先了解这个库的机制与流程,今天先从一个小例子开始我们的学习之旅。

搜索并采集结果的标题

需求如下:

打开百度搜索主页在输入框输入搜索内容(比如"爬虫")点击"百度一下"按钮,进行搜索把结果页面中的第一页的各个结果的主标题抓取下来Selenium 的麻烦之处

本系列始终围绕一点开展:"用代码操作浏览器",下面看看整个流程:

Python 代码通过 selenium 库,控制"浏览器驱动"程序(一个 exe 文件)"浏览器驱动"程序则发送指令操控"浏览器"

但是,市面上存在各种浏览器,而且就算只是一个厂商的浏览器也有不同的版本。怎么能保证我们的代码只需要写一次,就能控制不同的浏览器?

深入一点的流程图如下:

不同厂商不同版本的浏览器,都需要一个对应版本的"浏览器驱动"

"怎么案例都没开始,就在说 selenium 的不是呢?我到底还学不学?"

他有如下优点:

selenium 库已经开发很久,相对来说比较稳定selenium 在各个语言的库都是有 google 开发维护,因此不会出有些问题只在 Python 版本出现selenium 相比 pyppeteer 容易学一些有一个 selenium-ide 工具,能够把手工操作过程直接转换为 selenium 的代码

缺点:

不同版本不同厂商的浏览器需要不同的驱动程序无法精细控制请求过程的各种处理,如下无法在执行网站 js 代码之前,执行自己的 js 代码无法在登录阶段控制浏览器让人工登录获得 cookies,后续直接请求获得数据

如果你认为无法接受 selenium 的缺点,可以查看 pyppeteer 的相关文章(公众号:数据大宇宙 > py爬虫 > pyppeteer)



获得驱动

现在让我们来开始使用 selenium 解决我们的需求。

首先,使用 pip 安装 selenium

你可以在 jupyter notebook 的 cell 中执行 "!pip install selenium"也可以在 cmd 中执行 "pip install selenium"

由于我本机安装了 Google Chrome 浏览器,打开浏览器,看看浏览器的版本:

版本为 78.0.3904.70

接着到相关网站(私信我"python")下载对应的驱动:

点击进入浏览器版本号对应的目录下载 win32 版本压缩包解压后,里面有一个 chromedriver.exe ,这个就是"浏览器驱动"万事俱备

看过我的相关教学文章的小伙伴都知道,我很喜欢从语义角度去理解学习一个库。

selenium 本质上是控制浏览器,因此当我们使用它的时候,代码的语义应该与手工操作浏览器的过程大同小异才合理。

首先导入一些包:

下面来看看怎么用代码来描述我们的手工操作。

打开浏览器:

行1:webdriver.Chrome() ,实例化一个 Chrome 对象,如果你是其他浏览器,那么就要实例化对应浏览器的对象这代码相当于我们手工启动浏览器一样但是,代码报错了。他的意思是,他找不到"浏览器驱动"

的确,刚刚我们把驱动下载下来,但是 Python 怎么可能会知道去哪里找到那个驱动程序呢。

我们可以在实例化浏览器对象时,传入一个文件路径,告诉他程序的具体位置:

注意,要传入完整的文件路径我们也可以直接把"驱动程序"放置在代码所在目录此时可以看到浏览器被启动,默认开启一个空白页面,并且下方出现一行文字说,"此浏览器被控制"

输入百度搜索的网址:

行2:wd.get() ,传入网址即可注意,每次重复执行 webdriver.Chrome() 都会启动一个新的浏览器

鼠标移到输入框,点击一下,然后输入内容"爬虫":

这里的问题是,怎么用代码表达"鼠标移到输入框,点击一下"?

事实上,selenium 真可以模拟鼠标移动等操作(有些网站的登录验证码需要用鼠标拉动拼图都可以模拟),但是现在的情况我们不应该模拟鼠标,而是根据 html 标签定位即可。

此时我们使用浏览器的"开发者功能",进行定位即可。

由于篇幅关系,本文不详细讲解"开发者功能"的所有操作,详细讲解将放在公众号目录:数据大宇宙 > 爬虫工具 > 系列文章

也可以按快捷键 F12 启动此功能(大部分浏览器都可以)

下面用一个动态图展示操作过程:



点击功能区(右区)的左上角的小标签,开启定位模式此时鼠标移到页面区(左区),鼠标移到的地方,右区会显示此元素在 html 的位置我们看到,输入框是一个 input 标签,我们要在代码中告诉 selenium 找到这个 input 标签即可那么用啥"暗号"表示这个 input 标签呢?有2种常见的方式,css 选择器 或者 xpathselenium 文档中强烈推荐你使用 css 选择器我们选用 css 选择器,因此,在右区的 input 标签上,按鼠标右键,选 "copy" ,然后选择"copy selector" ,此时已经把"暗号"复制到剪切板上

看看代码:

行3:wd.find_element_by_css_selector ,使用 css 选择器找到元素,方法中传入刚刚复制的"暗号"(按 ctor + v ,粘贴即可)。注意是字符串,因此要用单引号包围此时,变量 input_box 则表示输入框



接着,输入内容"爬虫":

行4:input_box.send_keys ,往该元素发送按键,这个方法不仅仅能发送键盘的按键,还能往可输入的元素发送文本此时可以看到,浏览器已经输入了内容"爬虫",并且还可以看到下方已经出现搜索结果(这是因为现在的搜索引擎都提供这种边输入边查询的功能)

我们继续模拟点击输入框右边的"百度一下"这个按钮。

同样用"开发者功能",定位该元素,并复制 css 选择器表达字符串:

行7:用 css 选择器找到按钮行8:act_btn.click() 方法,对元素模拟点击现在浏览器显示的页面,就有我们需要的所有的内容

所有结果的主标题:

这个可能对初学者有点难度,因为我们这次需要一次选择多个元素(多个搜索结果的主标题),看看定位到的标签:

每个搜索结果,都是一个 div标签(上图右区下方红框)而所有的搜索结果的 div,都被包在一个 id='content_left' 的 div 标签里面(上图右区上方红框)

进一步看看我们需要的主标题在哪里:

我们要的数据都在一个 a 标签下并且这个 a 标签被放在一个 h3 标签里面

那么,现在我们要用 css 选择器表达以下语义:在一个div(id=content_left)里面,h3 标签里面的 a 标签的文本。div 与 h3 之间可能嵌套了多层。

得到的选择器表达式如下:

div[id=content_left] 表示 div 标签,他的 id 属性为 content_leftdiv 与 h3 之间用空格分开,表示他们是祖孙关系,就是 div 与 h3 之间有其他任意多的其他标签嵌套h3 与 a 之间,用">" 分开,表示父子关系,就是 a 标签就是在 h3 标签包围

调用代码如下:

行10:wd.find_elements_by_css_selector ,查找符合选择器的多个元素,注意方法名字的单词 elements 是复数的,与 行4 和 行7 的方法是不一样此时,titles 其实是一个列表,里面全是符合条件的 a 标签,但是我们的目标是 a 标签里面的文本行11:调用 a 标签的文本属性,获得其文本但是,你会发现结果啥也没有!!!



代码执行太快了

上面的代码之所以拿不到任何结果,是因为当执行到第10行的代码时,页面上还没有加载任何的结果。

如果是一个人在操作浏览器,那么你应该跟他说:嘿,一直到你看到那些结果,你再去提取主标题啊。

怎么表达"一直到你看到那些结果"?,selenium 有专门用于等待元素出现的机制,代码如下:

行10:实例化一个 WebDriverWait 对象,注意在一开始导入包的时候,我们导入了 import selenium.webdriver.support.wait as WA行11:调用 wait.until 方法,传入 lambda ,selenium 会定时执行里面的方法,直到里面的方法有返回对象此时可以见到,我们得到了结果关于更多等待机制的知识点,请关系本系列后续的文章

加上关闭浏览器的控制,完整代码如下:

总结

用代码控制 selenium 基本与人工操作一致,一般的流程:

启动浏览器定位元素(必要时要等元素出现)操作元素(点击或其他)不断进行定位与操作过程,直到出现目标页面,爬取数据即可

下一节,将介绍更多 selenium 的技巧,敬请关注!!

私信我"python",获取本系列文章所有相关资料和源码

标签: #python网页爬数据 #python浏览器控制