121.4_爬虫.PY_selenium的小操作

py

@[toc]

selenium:爬虫.py的一些小操作

2021年9月9日

23:29

DAY1 THE OPEN

硒元素:解决我的动态网页相关问题。

尝试爬了爬网站的表格,pandas的DataFrame对中文非常不友好,很多时候都是乱码。于是我就直接试着配置了个selenium环境,把数据存为把list再导出CSV格式,然后再在R里面进行数据清洗。

许多博主宣称selenium是所见即可爬,这很大程度激发了我的兴趣。争取再花一点点时间,深入了解一下。

原理和安装

客户端库到浏览器驱动,根据网上教程一步一步来,没有出现问题。

安装客户端库

使用pip命令安装

pip install selenium

安装浏览器驱动

嫌麻烦,于是就新下了个chrome。

然后下载了对应的驱动,注意到版本号要每个字都对上。再把驱动添加到环境变量,这样就可以不用再每次都指定路径了。

牛刀小试

1
2
3
4
5
6
7
8
9
from selenium import webdriver


wd = webdriver.Chrome() 
# 创建 WebDriver 对象,指明使用chrome浏览器驱动;此时会打开一个页面

wd.get('https://www.bilibili.com') 

# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址

太久没写了,网址都懒得打引号了。

1
wd.quit() #不用了,退出日志和浏览器

小结

至此,我们完成了简单的环境搭建,并且通过代码进入了网页。

wd = webdriver.Chrome() 运行之后,屏幕上回输出日志信息。说实话这日志对咱没啥用,可以这样关掉日志:

1
2
3
4
5
6
7
from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging']) 
# 加上参数,禁止 chromedriver 写屏

wd = webdriver.Chrome(options=options)
DAY1 THE END

DAY2 THE OPEN

选择元素的基本方法

了解过html和css,所有对元素一定不陌生。找到元素然后操作。

手动选择元素的方法

F12后在elements下看到web的元素,使用最左边的箭头快速选择要看的元素。

手动查找元素

根据元素的ID属性选择元素

1
2
<id="myid">
<id="s kw wrap">

这个就是元素的id

1
2
element = wd.find_element_by_id('myid')
# 根据id属性选择元素,返回元素对应的webelement对象。通过element对象进行一些操控。
1
2
3
4
5
element.send_key()
element.click()

#对元素进行输入
#对元素进行点击

根据class属性、tag名 选择元素

根据class属性 选择元素

element加不加’s'

一个class就是一类(classification),通常有多个元素具有相同的class属性,所以函数中element多了一个’s’。当然如果不加’s’将只返回第一个元素

1
2
3
4
5
wd.find_elements_by_class_name('class_name')
# 返回一个列表,里面都是class属性值为class_name的webelement对象。

wd.find_element_by_class_name('class_name')
# 只返回第一个元素

这样<class="class_name">的元素就被选中了。

把elements搞成text薅出来
1
2
3
4
for element in elements:
	print(element.text)

#text属性对应了该webelement对象对应元素在网页之中的文本内容。
元素属于多个类型

当元素属于多个类型时

<span class="CHINESE STUDIENT SON"></span>

可以通过他的任意一个类型选中他,但是不能这样写:

Element = wd.find_elements_by_class_name('CHINESE STUDENT')

根据 tag 选择元素

同样使用

wd.find_elements_by_tag_name('tb')

如此便选中了tag名为tb的元素对应的webelement对象。同样使用element.text属性来获得元素对应的文本。

1
2
3
4
5
6
7
8
9
elements = wd.find_elements_by_tag_name('div')
# 根据 tag name 选择元素,返回的是 一个列表
# 里面 都是 tag 名为 div 的元素对应的 WebElement对象

for element in elements:
  print(element.text)

# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容

NoSuchElementException 异常

没有符合的元素时抛出。有可能吧是真的没有,有可能是加载失败或者还没加载出来。

通过WebElement对象选择元素

元素筛选:Webelement.find与webdriver.find的区别

不仅 WebDriver对象有 选择元素 的方法, WebElement对象 也有选择元素的方法。

WebElement对象 也可以调用 find_elements_by_xxx, find_element_by_xxx 之类的方法

WebDriver 对象 选择元素的范围是 整个 web页面, 而WebElement 对象 选择元素的范围是 该元素的内部。

1
2
3
4
5
6
element = WebDriver.find_element_by_id('container')
spans = element.find_elements_by_tag_name('span')
# 限制 选择元素的范围是 id 为 container 元素的内部。

for span in spans:
  print(span.text)

如此便可以更加方便地完成内容筛选了

等待界面元素出现

在想服务器发出指令后等待个两秒钟:

1
2
3
4
from time import sleep

sleep(2)
# 等待个两秒钟

当然这是简单而粗暴的操作 ,Selenium提供了一个更合理的解决方案,是这样的:

当发现元素没有找到的时候, 并不 立即返回 找不到元素的错误。

而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,

或者超出指定最大等待时长,这时才 抛出异常或者返回空值。

1
2
3
#Webdriver 对象 有个方法叫 implicitly_wait。该方法接受一个参数, 用来指定 最大等待时长。

wd.implicitly_wait(10)

那么,后续所有的 find_element 或者 find_elements 之类的方法调用 都会采用上面的策略

当然,某些时候使用sleep也能够满足你的需求。

DAY2 THE END

CTRL-/