一、什么是selenium爬虫?
Selenium是一个用于Web浏览器自动化的工具,可以使用Python编写脚本来控制浏览器的行为。
Selenium爬虫是指使用Selenium库来模拟人为操作浏览器,实现对网页进行自动化处理和数据抓取的过程。
通过Selenium爬虫,可以实现自动登录、填写表单、点击按钮、抓取动态加载内容等操作,对于需要与JavaScript交互或者处理复杂页面的爬虫任务非常有用。
二、安装selenium库以及浏览器驱动
1、安装selenium库:通过pip命令即可
pip install selenium
2、下载浏览器驱动
如果你使用的是edge浏览器,那么先去浏览器点开设置-关于,查看你的浏览器的版本号,记住这个版本号,然后去浏览器搜索edge浏览器插件,打开官网,找到下面这个
点开这个链接后下看到下图这个页面,然后找到对应自己电脑浏览器版本的驱动,下载x64位的
下载好后解压那个文件夹,可以看到这样一个exe文件,不要点击它
然后找到你电脑装的Python所存放的文件夹,讲这个exe文件移动到Python文件夹下,到下图所示位置即可。
如果你不知道你的Python装到哪个位置去了,可以长按win+R打开命令提示符,输入命令where Python,第一条所示既是你当前安装并使用的Python位置
如果使用的是其他浏览器也是同样的方法去搜索,之后把驱动也是放在这个位置
三、爬取LOL英雄信息
1、request请求
按照以往学习的惯例我们要先获取URL在=再进行request请求,但是今天这个不行,用不了,试给大家看:
import requests
import fake_useragent
if __name__ == '__main__':
head={
'User-Agent':fake_useragent.UserAgent().random
}
#获取url
url='https://101.qq.com/'
#发送get请求
response=requests.get(url,headers=head)
#打印获取的内容
res=response.text
#将获取的内容写入html文件
with open('./lol.html','w',encoding='utf8') as fp:
fp.write(res)
pass
其创建一个html文件,并写入了js数据,但是打开这个html网页却不显示内容,实例如下:
这个页面和LOL英雄的页面只有几分相似,那就是背景图一样,那是因为requests请求发送的太快了,LOL页面打开需要停顿那么一秒,而在这停顿的间隙,request请求已经结束了,js代码还没有渲染完成,导致只爬取了一点点内容,所以下面就得用selenium来爬取
2、使用selenium方法
2.1 首先我们安装好上面的驱动以后,在代码框用代码from selenium import webdriver调用这个驱动,
2.2 利用代码driver=webdriver.Edge()确定需要使用的浏览器,如果你是用的是谷歌,那么就用webdriver.Chrome(),其他浏览器同样这么用,
2.3 获取URL,此时的URL为网页导航栏上的网址链接,然后使用驱动去发送请求,即driver.get(url),此时获取到的数据都存放在这个driver驱动里
from selenium import webdriver #从selenium包中调出浏览器驱动
if __name__ == '__main__':
driver=webdriver.Edge() #y用的什么浏览器就用这个驱动去调用,用Edge去访问
#请求页面,其为真实帮你打开浏览器的页面
driver.get('https://101.qq.com/#/hero')#将需要请求的页面URL拿过来
time.sleep(3)#使程序睡眠几秒,防止打开页面后快速结束
driver.close() #打开驱动就要关闭驱动,这里是关闭驱动
其运行结果如下图,其运行了给定的时间time.sleep(5)->5s,然后就关闭页面停止运行了
此时,我们已经成功获取到这个页面了,那么下面将开始去爬取这个页面里的英雄信息
3、使用find_element()定位页面上的单个元素,并返回一个表示该元素的WebElement对象
find_element()定位页面上的单个元素,而find_elements()用于定位多个元素,其内属性有多种方法可以调用,此时需要先导入一个包:
from selenium.webdriver.common.by import By
其中的By类定义了一组方法,用于定位网页元素。通过使用By类,可以指定不同的定位方式来找到特定的HTML元素,例如通过ID、名称、类名、标签名等。
4、常用的By
定位方法:
By.ID
: 通过元素的ID属性定位元素。
By.NAME
: 通过元素的名称属性定位元素。
By.CLASS_NAME
: 通过元素的类名定位元素。
By.TAG_NAME
: 通过元素的标签名定位元素。
By.LINK_TEXT
: 通过链接文本定位超链接元素。
By.PARTIAL_LINK_TEXT
: 通过部分链接文本定位超链接元素。
By.CSS_SELECTOR
: 通过CSS选择器定位元素。
By.XPATH
: 通过XPath表达式定位元素。
5、定位图片所处标签位置
如下图所示,图片全部存放于 li 标签内,所以我们就可以通过find_element去定位这个位置
利用代码获取到所有的图片存放的li标签
#用find_elements定位所有的li标签
li_list = driver.find_elements(By.XPATH,'//ul[@class="hero-list"]/li') #用于定位页面上的 多个元素,并返回表示该元素的WebElement对象
# print(li_list)
通过循环遍历出所有的li标签,然后正在对其进行find_element定位
#因为遍历出了一个li标签,所以用find_element
for li in li_list:#当前已在li标签下,不需要使用./来定位目录
img_url=li.find_element(By.XPATH,'div/div/img').get_attribute('src')
hero_name=li.find_element(By.XPATH,'div/p').text
print(img_url,hero_name)
其中get_attribute()表示需要打印出来的属性内容,括号内写入属性名称
此时打印出来的内容,则表示已经获取到所有的图片URL
有了这些图片的URL便可以通过上节课所学
的发送get请求获取二进制数据,再创建文件以jpg的格式将他们存放到本地了。
6、完整代码为:
from selenium import webdriver #从selenium包中调出浏览器驱动
from selenium.webdriver.common.by import By#By类定义了一组方法,用于定位网页元素。通过使用By类,可以指定不同的定位方式来找到特定的HTML元素,例如通过ID、名称、类名、标签名等
if __name__ == '__main__':
driver=webdriver.Edge() #用的什么浏览器就用这个驱动去调用,用Edge去访问
#请求页面,其为真实帮你打开浏览器的页面
driver.get('https://101.qq.com/#/hero')#将需要请求的页面URL拿过来
#强制等待
time.sleep(5)#使程序睡眠几秒,防止打开页面后快速结束
#用find_elements定位所有的li标签
li_list = driver.find_elements(By.XPATH,'//ul[@class="hero-list"]/li') #用于定位页面上的多个元素,并返回表示该元素的WebElement对象
# print(li_list)
#因为遍历出了一个li标签,所以用find_element
for li in li_list:#当前已在li标签下,不需要使用./来定位目录
img_url=li.find_element(By.XPATH,'div/div/img').get_attribute('src')
hero_name=li.find_element(By.XPATH,'div/p').text
print(img_url,hero_name)
driver.close() #打开驱动就要关闭驱动,这里是关闭驱动
四、无头模式、休眠程序
无头模式:
上述程序内容需要打开浏览器再打开网页后再获取数据,这样非常占用内存,消耗资源,我们可以通过导入新的方法进行无头模式,而不需要再打开浏览器的去获取数据其代码为:
#如果不想打开页面再去获取信息可以导入下列包
from selenium.webdriver.edge.options import Options
使用方法为:
#无头模式,即不需要去打开就可以网页获取网页信息
opt=Options()
opt.add_argument("--headless")
#可以将opt当做参数写入下列edge的括号里
driver = webdriver.Edge(options=opt)
后面的程序和其他的一样
休眠程序:
除了使用time.sleep()强制让程序休眠外,还有一种更温柔的方法,同样是导包
代码如下:
#用于当遇到期望遇到的东西时让程序休眠
from selenium.webdriver.support import expected_conditions as EC #
from selenium.webdriver.support.ui import WebDriverWait
其使用方法为:
WebDriverWait(driver,5).until(#其中driver为驱动,5为等待时间
EC.presence_of_element_located((By.XPATH,'//ul[@class="hero-list"]/li'))
)#By.XPATH为期望定位的用法,后面的标签定位是被期望定位到的位置,即当定位到这个位置则程序休眠5s
#通过find_element选择xpath方法去定位到英雄图片所对应的li标签
使用上述方法后有下列代码完成:
from selenium import webdriver #从selenium包中调出浏览器驱动
from selenium.webdriver.common.by import By#By类定义了一组方法,用于定位网页元素。通过使用By类,可以指定不同的定位方式来找到特定的HTML元素,例如通过ID、名称、类名、标签名等
#用于当遇到期望遇到的东西时让程序休眠
from selenium.webdriver.support import expected_conditions as EC #
from selenium.webdriver.support.ui import WebDriverWait
#如果不想打开页面再去获取信息可以导入下列包
from selenium.webdriver.edge.options import Options
if __name__ == '__main__':
#无头模式,即不需要去打开就可以网页获取网页信息
opt=Options()
opt.add_argument("--headless")
#可以将opt当做参数写入下列edge的括号里
driver = webdriver.Edge(options=opt)
#你用的什么浏览器就用这个驱动去调用,用Edge去访问
#请求页面,其为真实帮你打开浏览器的页面
driver.get('https://101.qq.com/#/hero')#将需要请求的页面URL拿过来
WebDriverWait(driver,5).until(#其中driver为驱动,5为等待时间
EC.presence_of_element_located((By.XPATH,'//ul[@class="hero-list"]/li'))
)#By.XPATH为期望定位的用法,后面的标签定位是被期望定位到的位置,即当定位到这个位置则程序休眠5s
#通过find_element选择xpath方法去定位到英雄图片所对应的li标签
#用find_elements定位所有的li标签
li_list = driver.find_elements(By.XPATH,'//ul[@class="hero-list"]/li') #用于定位页面上的多个元素,并返回表示该元素的WebElement对象
# print(li_list)
#因为遍历出了一个li标签,所以用find_element
for li in li_list:#当前已在li标签下,不需要使用./来定位目录
img_url=li.find_element(By.XPATH,'div/div/img').get_attribute('src')
hero_name=li.find_element(By.XPATH,'div/p').text
print(img_url,hero_name)
driver.close() #打开驱动就要关闭驱动,这里是关闭驱动