Python编程学习:Selenium自动化抓取动态网页数据实战教程

更新:11-09 现代故事 我要投稿 纠错 投诉

在之后,我无意中发现有自动化测试框架Selenium可以帮助我们处理这个问题。

简单说一下这个东西的用途。我们可以拨打编写代码让浏览器

1.自动加载网页; 2、模拟表单提交(如模拟登录),获取所需数据; 3、页面截图; 4、判断网页上是否发生了某些动作等。不过这个东西不支持浏览器功能。您需要与第三方浏览器一起使用它。

要支持以下浏览器,需要下载对应的浏览器驱动到Python对应的路径:

Chrome:https://sites.google.com/a/chromium.org/chromedriver/home

FireFox:https://github.com/mozilla/geckodriver/releases

PhantomJS: http://phantomjs.org/

IE:http://selenium-release.storage.googleapis.com/index.html

Edge:https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/

Opera:https://github.com/operasoftware/operachromiumdriver/releases

直接开始本节吧~

1.安装Selenium

这个很简单,直接通过pip命令行安装:

sudo pip install seleniumPS:记得公司的朋友问我为什么pip在win上执行不了,我下载了很多pip。

事实上,如果你安装了Python3,pip已经默认包含在内了。需要单独配置环境。

变量,pip的路径在Python安装目录的Scripts目录下~

只需在Path后面添加这个路径即可~

2.下载浏览器驱动

因为Selenium没有自带浏览器,所以需要依赖第三方浏览器并调用第三方

如果您有浏览器,则需要下载浏览器驱动程序。因为作者使用的是Chrome,所以这里我就使用

我们以Chrome 为例。其他浏览器可以自行搜索相关信息!打开Chrome 浏览器并输入:

chrome://version 可以查看Chrome浏览器版本的相关信息。这里我们主要关注版本号:

61,好的,然后去下面的网站查看对应的驱动版本号:

https://chromedriver.storage.googleapis.com/2.34/notes.txt

好,然后下载v2.34版本的浏览器驱动:

https://chromedriver.storage.googleapis.com/index.html?path=2.34/

下载完成后,解压zip文件,将解压后的chromedriver.exe复制到Python中

脚本目录。 (这里不用担心win32,在64位浏览器上也可以正常使用!)

PS:对于Mac,将解压后的文件复制到usr/local/bin目录。

对于Ubuntu,将其复制到:usr/bin目录

接下来我们写一段简单的代码来测试一下:

从硒导入网络驱动程序

browser=webdriver.Chrome() # 调用本地Chrome浏览器

browser.get("http://www.baidu.com") # 请求页面,浏览器窗口将打开

html_text=browser.page_source # 获取页面代码

browser.quit() # 关闭浏览器

当print(html_text) 执行这段代码时,它会自动启动浏览器并访问百度:

,控制台会输出HTML代码,即直接获取的Elements页面结构

JS 执行后,我们现在可以拍摄煎蛋女孩的照片了。

3.Selenium 简单实战:抓取煎蛋妹子图

直接分析Elements页面结构找到想要的关键节点:

显然这是我们抓到的小姐姐的照片。复制此URL 并查看我们打印出来的内容。

页面结构有没有这个东西:

是的,太好了,有了这个页面数据,我们通过BeautifulSoup 来获取我们

你想要的数据~

经过上面的过滤,就可以得到我们的女孩图片网址:

只需打开验证并点击:

再看下一页,只有30位小姐姐。这对我们来说显然是不够的。我们第一次加载它。

先拿到一波页码,然后就知道有多少页了,然后就可以自己拼接URL加载了。

不同的页面,比如这里一共是448页:

可以拼接成这样的URL:http://jandan.net/ooxx/page-448并过滤得到页码:

接下来我会完成代码,循环遍历每个页面的女士,然后下载到本地。

完整代码如下:

导入操作系统

从硒导入网络驱动程序

从bs4 导入BeautifulSoup

导入urllib.request

导入SSL

导入urllib.error

base_url="http://jandan.net/ooxx"

pic_save_path="输出/图片/简单/"

# 下载图片

def download_pic(url):

正确的网址=网址

如果url.startswith("//"):

正确的网址=网址[2:]

如果不是url.startswith("http"):

正确的网址="http://" + 正确的网址

打印(正确的网址)

标题={

"主持人": "wx2.sinaimg.cn",

"User-Agent": "Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如Gecko)"

"Chrome/61.0.3163.100 Safari/537.36"

}

尝试:

req=urllib.request.Request( Correct_url, headers=headers)

resp=urllib.request.urlopen(req)

pic=resp.read()

pic_name=Correct_url.split("/")[-1]

打开(pic_save_path + pic_name,"wb+")为f:

f.write(图片)

except (OSError, urllib.error.HTTPError, urllib.error.URLError, Exception) 作为Reason:

打印(str(原因))

#打开浏览器模拟请求

def browser_get():

浏览器=webdriver.Chrome()

browser.get("http://jandan.net/ooxx")

html_text=浏览器.page_source

page_count=get_page_count(html_text)

# 循环拼接URL访问

对于范围内的页面(page_count, 0, -1):

page_url=base_url + "/page-" + str(页面)

print("解析:" + page_url)

browser.get(page_url)

html=浏览器.page_source

获取梅子网址(html)

browser.quit()

# 获取总页数

def get_page_count(html):

汤=BeautifulSoup(html, "html.parser")

page_count=soup.find("span", attrs={"class": "当前评论页"})

返回int(page_count.get_text()[1:-1]) - 1

# 获取每页的女士

def get_meizi_url(html):

汤=BeautifulSoup(html, "html.parser")

ol=soup.find("ol", attrs={"class": "评论列表"})

href=ol.findAll("a", attrs={"class": "view_img_link"})

对于href: 中的a

下载图片(a["href"])

如果__name__=="__main__":

ssl._create_default_https_context=ssl._create_unverified_context

如果不是os.path.exists(pic_save_path):

os.makedirs(pic_save_path)

browser_get()运行结果:

看看我们的输出文件夹~

学习Python爬虫,一天比一天瘦……

4.PhantomJS

PhantomJS无界面浏览器,特点:它将网站加载到内存中并执行页面上的功能

JavaScript,因为不会展示图形界面,在比完整的浏览器要高效上运行。

(部分Linux主机没有图形界面,无法安装Chrome等浏览器。

这个问题可以通过PhantomJS 来规避)。

Win上安装PhantomJS

1、官网下载:http://phantomjs.org/download.html压缩包; 2.解压: phantomjs-2.1.1-windows.zip 并将其放在你想要的位置; 3.配置环境变量目录/bin例如我的:; 4、打开cmd,输入:phantomjs --version,验证是否配置成功;

Ubuntu/MAC上安装PhantomJS:

sudo apt-get install phantomjs!关于PhantomJS的重要说明

今年4月,Phantom.js的维护者宣布退出PhantomJS。

这意味着这个项目可能不再维护了!Chrome和FireFox也开始了

提供Headless模式(不用挂浏览器),所以估计使用PhantomJS的朋友

也会慢慢迁移到这两个浏览器上。 Windows Chrome 需要60 或更高版本才能支持

Headless模式,启用Headless模式也很简单:

Selenium官方文档还写道:

当运行时也会报告此警告:

5.Selenium实战:模拟登录CSDN,并保存Cookie

CSDN登录网站: https://passport.csdn.net/account/login

分析完页面结构,不难找到对应的登录输入框和登录按钮:

我们要做的就是在这两个节点输入账号密码,然后触发登录按钮。

同时将cookie保存在本地,以后就可以使用cookie来访问相关页面了~

我们先写一个模拟登录方法:

找到输入账号密码的节点,设置自己的账号密码,然后找到登录

单击按钮节点,然后等待登录成功。登录成功后可以进行比较

current_url 是否已更改。然后在这里保存cookie

我使用pickle 库,但您可以使用其他库,例如json 或字符串连接。

然后保存到本地。如果没有意外发生,您应该能够获取cookie,然后使用它

Cookie 访问主页。

通过add_cookies方法设置Cookies。参数是字典类型。此外,您必须首先

访问一次get链接,然后设置cookie,否则会报无法设置cookie的错误!

您可以通过查看右下角是否变为登录状态来了解您是否已使用cookies登录成功:

6.Selenium 常用函数

作为自动化测试的工具,Seleninum 自然提供了很多自动化操作的功能。

下面列出了我个人认为比较常用的功能。更多信息请参见官方文档:

官方API文档:http://seleniumhq.github.io/selenium/docs/api/py/api.html

1) 定位元素

find_element_by_class_name:基于类的位置find_element_by_css_selector:基于css 的位置find_element_by_id:基于id 的位置find_element_by_link_text:基于链接文本的位置find_element_by_name:基于节点名称的位置010 -59000:根据链接的文本定位来定位,只要包含在整个文本中即可find_element_by_partial_link_text:通过标签定位find_element_by_tag_name:使用Xpath进行定位PS:将element改为elements,将定位到所有包含该链接的元素满足条件并返回一个List

例如:find_element_by_xpath

2) 鼠标动作

有时需要在页面上模拟鼠标操作,如:单击、双击、右键、按住、拖动等。

可以导入find_elements_by_class_name类:ActionChains使用selenium.webdriver.common.action_chains.ActionChains调用对应节点的行为

ActionChains(driver).XXX:点击某个节点;click(element):点击节点并按住;click_and_hold(element):右键单击节点;context_click(element):双击节点;double_click(element):按住一个节点并将其拖动到另一个节点;拖

_and_drop_by_offset(source, xoffset, yoffset):按住节点按偏移拖拽key_down:按下特殊键,只能用(Control, Alt and Shift),比如Ctrl+C ActionChains(driver).key_down(Keys.CONTROL).send_keys("c").key_up(Keys.CONTROL).perform();key_up:释放特殊键;move_by_offset(xoffset, yoffset):按偏移移动鼠标;move_to_element(element):鼠标移动到某个节点的位置;move_to_element_with_offset(element, xoffset, yoffset):鼠标移到某个节点并偏移;pause(second):暂停所有的输入多少秒;perform():执行操作,可以设置多个操作,调用perform()才会执行;release():释放鼠标按钮reset_actions:重置操作send_keys(keys_to_send):模拟按键,比如输入框节点.send_keys(Keys.CONTROL,"a") 全选输入框内容,输入框节点.send_keys(Keys.CONTROL,"x")剪切,模拟回退: 节点.send_keys(keys.RETURN);或者直接设置输入框内容:输入框节点.send_keys("xxx");send_keys_to_element(element,keys_to_send):和send_keys类似;

3) 弹窗

对应类:selenium.webdriver.common.alert.Alert,感觉应该用得不多...

如果你触发了某个时间,弹出了对话框,可以调用下述方法获得对话框:alert = driver.switch_to_alert(),然后可以调用下述方法: accept():确定dismiss():关闭对话框send_keys():传入值text():获得对话框文本

4)页面前进,后退,切换

切换窗口: driver.switch_to.window("窗口名") 或者通过window_handles来遍历 for handle in driver.window_handles:       driver.switch_to_window(handle) driver.forward() #前进 driver.back() # 后退

5) 页面截图

driver.save_screenshot("截图.png")

6) 页面等待

现在的网页越来越多采用了 Ajax技术,这样程序便不能确定何时某个元素完全 加载出来了。如果实际页面等待时间过长导致某个dom元素还没出来,但是你的 代码直接使用了这个WebElement,那么就会抛出NullPointer的异常。 为了避免这种元素定位困难而且会提高产生ElementNotVisibleException的概率。 所以 Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待显式等待: 显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有 找到元素,那么便会抛出异常了。 from selenium import webdriver from selenium.webdriver.common.by import By # WebDriverWait 库,负责循环等待 from selenium.webdriver.support.ui import WebDriverWait # expected_conditions 类,负责条件出发 from selenium.webdriver.support import expected_conditions as EC driver = webdriver.PhantomJS() driver.get("http://www.xxxxx.com/loading") try: # 每隔10秒查找页面元素 id="myDynamicElement",直到出现则返回 element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成, 如果本来元素就是存在的,那么会立即返回。 下面是一些内置的等待条件,你可以直接调用这些条件,而不用自己 写某些等待条件了。 title_is title_contains presence_of_element_located visibility_of_element_located visibility_of presence_of_all_elements_located text_to_be_present_in_element text_to_be_present_in_element_value frame_to_be_available_and_switch_to_it invisibility_of_element_located element_to_be_clickable – it is Displayed and Enabled. staleness_of element_to_be_selected element_located_to_be_selected element_selection_state_to_be element_located_selection_state_to_be alert_is_present隐式等待: 隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。 from selenium import webdriver driver = webdriver.PhantomJS() driver.implicitly_wait(10) # seconds driver.get("http://www.xxxxx.com/loading") myDynamicElement = driver.find_element_by_id("myDynamicElement")当然如果不设置,默认等待时间为0。

7.执行JS语句

driver.execute_script(js语句) 比如滚动到底部:js = document.body.scrollTop=10000driver.execute_script(js)

小结

本节讲解了一波使用Selenium自动化测试框架来抓取JavaScript动态生成数据,Selenium需依赖于第三方的浏览器,要注意PhantomJS无界面浏览器过时的 问题,可以使用Chrome和FireFox提供的HeadLess来替换;通过抓取煎蛋妹子 图以及模拟CSDN自动登录的例子来熟悉Selenium的基本使用,还是收货良多的。 当然Selenium的水还是很深的,当前我们能够使用它来应付JS动态加载数据页面 数据的抓取就够了。 另最近天气骤冷,各位小伙伴记得适时添衣~顺道记录下自己的想到的东西: 1.不是每个网站都是像CSDN一样不需要验证码就能够登录的,验证码还分几代, 普通的数字模糊下,滑条,而像简书掘金用那种人机检测的是比较新的,目前还 不知道怎么解决,有知道的小伙伴告诉下呗~2.像掘金,简书等那种抓取文章,为了反爬虫,需要登录才能查看全文...本节源码下载: https://github.com/coder-pig/ReptileSomething本节参考文献: Selenium官方文档Python爬虫Selenium和PhantomJS系列之十三来啊,Py交易啊想加群一起学习Py的可以加下,智障机器人小Pig,验证信息里包含:PythonpythonpyPy加群交易屁眼中的一个关键词即可通过;

用户评论

■□丶一切都无所谓

小猪终于开始学爬虫了!

    有12位网友表示赞同!

尘埃落定

Selenium真香啊,各种网站都能抓数据。

    有17位网友表示赞同!

我怕疼别碰我伤口

动态的数据获取确实有点门槛,需要仔细研究。

    有15位网友表示赞同!

命里缺他

学习Python就是为了学习这些实用工具吧。

    有17位网友表示赞同!

那伤。眞美

小猪学东西的速度比我还快!

    有12位网友表示赞同!

生命一旅程

我以前也用过Selenium,感觉很好用。

    有7位网友表示赞同!

站上冰箱当高冷

抓取网页数据可以做很多有意思的事情啊!

    有12位网友表示赞同!

烟雨离殇

这应该是很厉害的技能!

    有5位网友表示赞同!

琴断朱弦

期待小猪分享学习心得!

    有16位网友表示赞同!

一个人的荒凉

学习爬虫感觉很有挑战性!

    有20位网友表示赞同!

堕落爱人!

我也想学爬虫,回头好好看看Python教程。

    有5位网友表示赞同!

醉婉笙歌

小猪这次的选择看起来很棒!

    有20位网友表示赞同!

予之欢颜

网页数据真是宝藏啊!

    有5位网友表示赞同!

此生一诺

这篇文章一定会很有用,谢谢小猪的分享!

    有8位网友表示赞同!