爬⾍-----selenium模块⾃动爬取⽹页资源selenium介绍与使⽤
1 selenium介绍
什么是selenium?selenium是Python的⼀个第三⽅库,对外提供的接⼝可以操作浏览器,然后让浏览器完成⾃动化的操作。
selenium最初是⼀个⾃动化测试⼯具,⽽爬⾍中使⽤它主要是为了解决requests⽆法直接执⾏JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟浏览器的操作,⽐如跳转、输⼊、点击、下拉等,来拿到⽹页渲染之后的结果,可⽀持多种浏览器.
2 下载安装
下载放到python安装路径的scripts⽬录中即可,注意最新版本是2.38,并⾮2.9
pip install selenium
3 使⽤
from selenium import webdriver
from time import sleep
from selenium.webdrivermon.keys import Keys # 键盘上操作键的模块
# 后⾯是你的浏览器驱动位置,记得前⾯加r'','r'是防⽌字符转义的
driver = webdriver.Chrome()
# ⽤get打开百度页⾯
<("www.baidu")
# 查页⾯的“设置”选项,并进⾏点击
driver.find_elements_by_link_text('设置')[0].click()
sleep(2)
# # 打开设置后到“搜索设置”选项,设置为每页显⽰50条
driver.find_elements_by_link_text('搜索设置')[0].click()
sleep(2)
# 选中每页显⽰50条
m = driver.find_element_by_id('nr')
sleep(2)
m.find_element_by_xpath('//*[@id="nr"]/option[3]').click()
m.find_element_by_xpath('.//option[3]').click()
sleep(2)
# 点击保存设置
driver.find_elements_by_class_name("prefpanelgo")[0].click()
sleep(2)
# 处理弹出的警告页⾯确定accept() 和取消dismiss()
driver.switch_to.alert().accept()
sleep(2)
# 到百度的输⼊框,并输⼊美⼥
driver.find_element_by_id('kw').send_keys('美⼥')
sleep(2)
# 点击搜索按钮
driver.find_element_by_id('su').click()
# (或者在输⼊框输⼊之后直接driver.send_keys(Keys.ENTER)表⽰按下回车键)
sleep(2)
# 在打开的页⾯中到“Selenium - 开源中国社区”,并打开这个页⾯
driver.find_elements_by_link_text('美⼥_百度图⽚')[0].click()
sleep(3)
# 关闭浏览器
driver.quit()
4 元素定位
find_element_by_id()
find_element_by_name()
find_element_by_class_name()
find_element_by_tag_name()
find_element_by_link_text()
find_element_by_partial_link_text()
find_element_by_xpath()
find_element_by_css_selector()
# 这些都有对应的 find_相对应
# 注意: find_拿到的是⼀个列表
find_拿到的是⼀个tag对象
5 节点交互
Selenium可以驱动浏览器来执⾏⼀些操作,也就是说可以让浏览器模拟执⾏⼀些动作。⽐较常见的⽤法有:输⼊⽂字时⽤send_keys()⽅法,清空⽂字时⽤clear()⽅法,点击按钮时⽤click()⽅法。
from selenium import webdriver
import time
browser = webdriver.Chrome()
<('www.taobao')
input = browser.find_element_by_id('q')
input.send_keys('MAC') # 输⼊搜索词条
time.sleep(1)
input.clear() # 清除词条
input.send_keys('IPhone')
button = browser.find_element_by_class_name('btn-search')
button.click() #点击搜索按钮
6 动作链
在上⾯的实例中,⼀些交互动作都是针对某个节点执⾏的。⽐如,对于输⼊框,我们就调⽤它的输⼊⽂字和清空⽂字⽅法;对于按钮,就调⽤它的点击⽅法。其实,还有另外⼀些操作,它们没有特定的执⾏对象,⽐如⿏标拖曳、键盘按键等,这些动作⽤另⼀种⽅式来执⾏,那就是动作链。⽐如,现在实现⼀个节点的拖曳操作,将某个节点从⼀处拖曳到另外⼀处,可以这样实现:
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
browser = webdriver.Chrome()
url = 'www.runoob/try/try.php?filename=jqueryui-api-droppable'
<(url)
browser.switch_to.frame('iframeResult')
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser)
selenium怎么使用# actions.drag_and_drop(source, target)
actions.click_and_hold(source).perform() # 点击并且按住
time.sleep(1)
time.sleep(1)
7 执⾏js动作
对于某些操作,Selenium API并没有提供。⽐如,下拉进度条,它可以直接模拟运⾏JavaScript,此时使⽤execute_script()⽅法即可实现,代码如下:
from selenium import webdriver
browser = webdriver.Chrome()
<('www.jd/')
如何判断滚动条已经下拉到最后的位置了? 代码如下:
from selenium import webdriver
from time import sleep
url = "movie.douban/typerank?type_name=%E6%81%90%E6%80%96&type=20&interval_id=100:90&action="
path = "./phantomjs-2.1.1-windows/"
height_list = [] # ⽤来放每次的拖动滚动条后页⾯的最⼤⾼度
browser = webdriver.PhantomJS(executable_path=path)
<(url)
height_list.ute_script("return document.body.scrollHeight")) # 放第⼀次拖动滚动条后页⾯的最⼤⾼度
while 1:
sleep(1)
check_height = ute_script("return document.body.scrollHeight")
# 获取每次拖动的⽂档⾼度
if check_height == height_list[-1]: # 判断拖动滚动条后的最⼤⾼度与上⼀次的最⼤⾼度的⼤⼩,相等表明到了最底部
break
height_list.append(check_height)
print(height_list) # [1000, 2480, 4391, 6301, 8211, 10121, 12031, 13941, 15851, 17761, 19098]
8 延时等待
在Selenium中,get()⽅法会在⽹页框架加载结束后结束执⾏,此时如果获取page_source,可能并不是浏览器完全加载完成的页⾯,如
果某些页⾯有额外的Ajax请求,我们在⽹页源代码中也不⼀定能成功获取到。所以,这⾥需要延时等待⼀定时间,确保节点已经加载出来。这⾥等待的⽅式有两种:⼀种是隐式等待,⼀种是显式等待。
隐式等待:
当使⽤隐式等待执⾏测试的时候,如果Selenium没有在DOM中到节点,将继续等待,超出设定时间后,则抛出不到节点的异常。换句话说,当查节点⽽节点并没有⽴即出现的时候,隐式等待将等待⼀段时间再查DOM(在这段时间之内不会查, n秒之后再进⾏查),默认的时间是0。⽰例如下:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdrivermon.by import By #按照什么⽅式查,By.ID,By.CSS_SELECTOR
from selenium.webdrivermon.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页⾯加载某些元素
browser=webdriver.Chrome()
#隐式等待:在查所有元素时,如果尚未被加载,则等10秒, 10秒之后再⼀次查
browser.implicitly_wait(10)
<('www.baidu')
input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美⼥')
input_tag.send_keys(Keys.ENTER)
contents=browser.find_element_by_id('content_left') #没有等待环节⽽直接查,不到则会报错
print(contents)
browser.close()
显⽰等待:
隐式等待的效果其实并没有那么好,因为我们只规定了⼀个固定时间,⽽页⾯的加载时间会受到⽹络条件的影响。这⾥还有⼀种更合适的显式等待⽅法,它指定要查的节点,然后指定⼀个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdrivermon.by import By #按照什么⽅式查,By.ID,By.CSS_SELECTOR
from selenium.webdrivermon.keys import Keys #键盘按键操作
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页⾯加载某些元素
browser=webdriver.Chrome()
<('www.baidu')
input_tag=browser.find_element_by_id('kw')
input_tag.send_keys('美⼥')
input_tag.send_keys(Keys.ENTER)
#显式等待:显式地等待某个元素被加载
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))
contents=browser.find_element(By.CSS_SELECTOR,'#content_left')
print(contents)
browser.close()
9 获取tag节点的信息
通过page_source属性可以获取⽹页的源代码,接着就可以使⽤解析库(如正则表达式、Beautiful Soup、pyquery等)来提取信息了。不过,既然Selenium已经提供了选择节点的⽅法,返回的是WebElement类型,那么它也有相关的⽅法和属性来直接提取节点信息,如属性、⽂本等。这样的话,我们就可以不⽤通过解析源代码来提取信息了,⾮常⽅便。
from selenium import webdriver
from selenium.webdrivermon.by import By #按照什么⽅式查,By.ID,By.CSS_SELECTOR
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait #等待页⾯加载某些元素
browser=webdriver.Chrome()
<('www.amazon/')
wait=WebDriverWait(browser,10)
wait.until(EC.presence_of_element_located((By.ID,'cc-lm-tcgShowImgContainer')))
tag=browser.find_element(By.CSS_SELECTOR,'#cc-lm-tcgShowImgContainer img')
#获取标签属性,
_attribute('src'))
#获取标签ID,位置,名称,⼤⼩(了解)
print(tag.id)
print(tag.location) # {'x': 0, 'y': 133}
print(tag.tag_name)
print(tag.size) # {'height': 1453, 'width': 661}
browser.close()
phantomJs介绍与使⽤
1 PhantomJS介绍
PhantomJS是⼀款⽆界⾯的浏览器,其⾃动化操作流程和上述操作⾕歌浏览器是⼀致的。由于是⽆界⾯的,为了能够展⽰⾃动化操作流程,PhantomJS为⽤户提供了⼀个截屏的功能,使⽤save_screenshot("xxx.png")函数实现。
重点:selenium+phantomjs 就是爬⾍终极解决⽅案:有些⽹站上的内容信息是通过动态加载js形成的,所以使⽤普通爬⾍程序⽆法回去动态加载的js内容。例如⾖瓣电影中的电影信息是通过下拉操作动态加载更多的电影信息。
from selenium import webdriver
import time
"""
phantomjs, 完完全全模拟浏览器访问url, 期间没有可视化界⾯
"""
time.sleep(1)
bro = webdriver.PhantomJS(executable_path="./phantomjs-2.1.1-windows/")
<("www.baidu/")
time.sleep(2)
text_input = bro.find_element_by_id("kw")
value_btn = bro.find_element_by_id("su")
text_input.send_keys("粪叉⼦")
value_btn.click()
time.sleep(2)
js = "window.scrollTo(0,document.body.scrollHeight)"
time.sleep(2)
page_text = bro.page_source
print(page_text)
bro.quit() # 同 bro.close()
2 Google⽆头浏览器
由于PhantomJs最近已经停⽌了更新和维护,所以推荐⼤家可以使⽤⾕歌的⽆头浏览器,是⼀款⽆界⾯的⾕歌浏览器。
from selenium import webdriver
import time
from selenium.webdriver.chrome.options import Options
"""
使⽤⽆头浏览器的基本配置
"""
chorme_options = Options()
chorme_options.add_argument("--headless")
chorme_options.add_argument("--disable-gpu")
time.sleep(1)
bro = webdriver.Chrome(executable_path="./", chrome_options=chorme_options)
<("www.baidu/")
time.sleep(1)
text_input = bro.find_element_by_id("kw")
value_btn = bro.find_element_by_id("su")
text_input.send_keys("玛莎拉斯")
value_btn.click()
time.sleep(1)
js = "window.scrollTo(0,document.body.scrollHeight)"
time.sleep(1)
page_text = bro.page_source
print(page_text)
bro.quit()
图⽚的懒加载技术
1 图⽚懒加载概念:
图⽚懒加载是⼀种⽹页优化技术。图⽚作为⼀种⽹络资源,在被请求时也与普通静态资源⼀样,将占⽤⽹络资源,⽽⼀次性将整个页⾯的所有图⽚加载完,将⼤⼤增加页⾯的⾸屏加载时间。为了解决这种问题,通过前后端配合,使图⽚仅在浏览器当前视窗内出现时才加载该图⽚,达到减少⾸屏图⽚请
求数的技术就被称为“图⽚懒加载”。
2 ⽹站⼀般如何实现图⽚懒加载技术呢?
在⽹页源码中,在img标签中⾸先会使⽤⼀个“伪属性”(通常使⽤src2,)去存放真正的图⽚链接⽽并⾮是直接存放在src属性中。当图⽚出现到页⾯的可视化区域中,会动态将伪属性替换成src属性,完成图⽚的加载。
3 站长素材案例后续分析:通过细致观察页⾯的结构后发现,⽹页中图⽚的链接是存储在了src2这个伪属性中,代码如下:
from bs4 import BeautifulSoup
import requests
# 爬取站长回家图⽚链接 sc.chinaz/tupian/meinvtupian.html
url = "sc.chinaz/tupian/meinvtupian.html"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36"
}
page = (url,headers=headers)
soup = ,"lxml")
div_box = soup.find_all("div",id="container")
for pic_box in div_box:
src = pic_box.find_all("img")
for i in src:
print(i.attrs["alt"])
print(i.attrs["src"]) # 没有src属性, 直接报错
print(i.attrs["src2"]) # src2伪属性
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论