from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options # 導入自定義配置模塊
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
chorme_options=Options()
# chrome_options.add_argument('window-size=1920x3000') #指定瀏覽器分辨率
chrome_options.add_argument('--disable-gpu') #谷歌文檔提到須要加上這個屬性來規避bug
# chrome_options.add_argument('--hide-scrollbars') #隱藏滾動條, 應對一些特殊頁面
chrome_options.add_argument('blink-settings=imagesEnabled=false') #不加載圖片, 能夠提高速度
chrome_options.add_argument('--headless') #瀏覽器不提供可視化頁面. linux下若是系統若是無界面不加這條會啓動失敗
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])#取消瀏覽器驅動提示
# 若是將驅動的路徑設置到環境變量中 能夠不用傳參數
# options 表示配置項
driver=Chrome(options=chrome_option)
driver.get('https://www.baidu.com')
tag = driver.find_element_by_class_name("index-logo-src")
# tag = driver.find_element_by_css_selector(".index-logo-src")#css選擇器
#
#
#
#
#
# print(tag)
#
# #標籤相關內容
# print(tag.text)
# #print(tag.parent) # 獲得的是driver對象 不是父標籤
# print(tag.get_attribute("src"))
# print(tag.tag_name)
#
# 隱式等待
driver.implicitly_wait(10) # 當要查找的某個元素不存在時 會過一下子在查找一次(輪詢)知道找到未知 一致到超過10就報錯
# key_input = driver.find_element(By.ID,"kw")
# 找到輸入框
key_input = driver.find_element_by_id("kw")
key_input.send_keys("基佬")
key_input.send_keys(Keys.ENTER)
# 顯示等待 明確的等待某一個元素 知足某個條件
# 傳入 要等到的driver 和 等到超時時間
# 等到頁面上出現了一個id爲content_left 的元素位爲止 最長等10秒
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,"content_left")))#傳元祖
print("============================")
# 獲取搜索結果 若是直接獲取元素 可能由於頁面沒有加載完畢 致使獲取失敗
div = driver.find_element_by_id("content_left")
print(div)
import time
time.sleep(1)
key_input = driver.find_element_by_id("kw")
key_input.clear() # 清空輸入框
key_input.send_keys("泰國美女")
key_input.send_keys(Keys.ENTER)
動做鏈
指的是一系列動做的集合
例如: 滑動驗證
1.點擊並按住
2.移動鼠標
3.移到指定位置 鬆手
"""
from selenium.webdriver import Chrome
from selenium.webdriver import ActionChains
driver = Chrome(r"D:\jerry\spiderDay3\selenium模塊\chromedriver.exe")
driver.get("http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
driver.implicitly_wait(5)
# 切換fream
driver.switch_to.frame("iframeResult")
# 獲取請拖拽我這個標籤
tag = driver.find_element_by_id("draggable")
print(tag.location)
# 獲取目標位置的標籤
tag2 = driver.find_element_by_id("droppable")
print(tag2.location)
# x移動距離
# dis = tag2.location["x"] - tag.location["x"]
# 建立一個動做對象
# asc = ActionChains(driver)
# asc.click_and_hold(tag).perform() # perform()表示執行這個動做 點擊並按住
# asc.move_to_element(tag2).perform() # 移動標籤到tag2的位置
# asc.release().perform() # 鬆手
# 上述方式 不像人 很容易被判斷爲機器人(程序)
# 線性移動
asc = ActionChains(driver)
asc.click_and_hold(tag).perform()
# 循環逐漸移動
while tag.location["x"] < tag2.location["x"]:
ActionChains(driver).move_by_offset(1,0).perform()
asc.release().perform()
# # 若是要訪問當前fream 之上(父輩)的內容 須要回到父級fream
# driver.switch_to.parent_frame()
# driver.find_element_by_id("textareaCode")
from selenium.webdriver import Chrome
driver = Chrome(r"D:\jerry\spiderDay3\selenium模塊\chromedriver.exe")
driver.get("https://www.baidu.com")
# driver.execute_script("alert('你是殺馬特碼?')")
# 導航(前進後退)
# driver.get("https://www.baidu.com")
# driver.get("https://www.qq.com")
# driver.get("https://www.sina.com")
# driver.get("https://www.4399.com")
#
#
# driver.back()# 後退
# driver.forward() # 前進
# 切換選項卡
driver.execute_script("window.open()")
# print(driver.window_handles) # 獲取全部windows對象
driver.switch_to.window(driver.window_handles[1])
driver.get("https://www.qq.com")
driver.switch_to.window(driver.window_handles[0])
"""
xpath 也是一種用於解析xml文檔數據的方式
xml path
"""
doc = """
<?xml version="1.0" encoding="ISO-8859-1"?>
<html>
<body>
<bookstore id="test" class="ttt">
<book id= "1" class = "2">
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book id = "2222222222222">11111111111111111111
<title lang="abc">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
<a></a>
</body>
</html>
"""
from lxml import etree
html = etree.HTML(doc)
print(html.xpath("/bookstore")) # 從根標籤開始找全部匹配的
print(html.xpath("//bookstore")) # 全文中找全部匹配的
# 通配符 *
print(html.xpath("//book"))
print(html.xpath("//*"))
# 獲取屬性
print(html.xpath("//bookstore/@id"))
print(html.xpath("//bookstore/@*"))
# 嵌套
print(html.xpath("//bookstore/book/title/text()"))
# 加上謂語(條件) ==========================================================================================
# 指定要獲取的索引
# print(html.xpath("//bookstore/book[1]/title/text()")) # 獲取第一個
# print(html.xpath("//bookstore/book[last()-1]/title/text()")) # last() 最後一個 last()-1 倒數第二個
# print(html.xpath("//bookstore/book[position()>1]/title/text()")) # 索引大於1的
# print(html.xpath("//book[price > 30]"))
# # xpath 原生 既能查找屬性 又能查找標籤 而在selenium只能查找標籤
#
#
# # 查找price的值大於30的book標籤
# e = html.xpath("//book[price > 30]")[0]
# print(type(e))
# from lxml.etree import _Element
# print(e.text) # 訪問文本 不包含子標籤的文本
# print(e.attrib) # 訪問屬性
# 用屬性來做限制
# 只要存在lang屬性便可
print(html.xpath("//*[@lang]"))
# 找的是具有lang而且值爲abc的標籤
print(html.xpath("//*[@lang='abc']")[0].attrib)
# 只要 有屬性便可
print(html.xpath("//*[@*]"))
# 多個匹配條件
print(html.xpath("//title|//price"))
# 軸匹配 (先拿到一個標籤 在相對這個標籤找其餘標籤) ===========================================
print(html.xpath("//bookstore/ancestor::*")) # 全部先輩
print(html.xpath("//bookstore/ancestor::body")) # 全部叫body的先輩
print(html.xpath("//bookstore/ancestor-or-self::*")) # 全部叫body的先輩
# 獲取屬性
print(html.xpath("//bookstore/attribute::id"))
print(html.xpath("//bookstore/@id"))
# 全部子級標籤
print(html.xpath("//bookstore/child::*"))
# 全部後代標籤
print(html.xpath("//bookstore/descendant::*"))
# 在這個標籤後面的全部標籤 與層級無關
print(html.xpath("//book[1]/following::*"))
# 它弟弟們
print(html.xpath("//book[1]/following-sibling::*"))
# 它哥哥們
print(html.xpath("//book[1]/preceding-sibling::*"))
# 獲取父級
# print(html.xpath("//book[1]/parent::*"))
# 獲取既有id屬性 又有class屬性的標籤
print(html.xpath("//*[@id and @class]"))
筆記整理
## selenium介紹:selenium最初是一個自動化測試工具,而爬蟲中使用它主要是爲了解決requests沒法直接執行JavaScript代碼的問題selenium本質是經過驅動瀏覽器,徹底模擬瀏覽器的操做,好比跳轉、輸入、點擊、下拉等,來拿到網頁渲染以後的結果,可支持多種常見的瀏覽器```pythonfrom selenium import webdriverbrowser=webdriver.Chrome()browser=webdriver.Firefox()browser=webdriver.PhantomJS()browser=webdriver.Safari()browser=webdriver.Edge()```官網:http://selenium-python.readthedocs.io## 環境搭建#### 1.在python中使用selenium須要先安裝對應的模塊```pythonpip install selenium```#### 2.selenium的原理是操做驅動瀏覽器來完成對目標頁面的請求與渲染,因此須要下載對應的瀏覽器驅動程序,推薦使用chrome鏡像地址:https://npm.taobao.org/mirrors/chromedriver/須要注意的是,驅動程序版本須要與瀏覽器版本對應,你能夠打開chrome的關於瀏覽器查看到具體版本。#### 驅動與瀏覽器的版本對應關係ChromeDriver v2.45 (2018-12-10)----------Supports Chrome v70-72ChromeDriver v2.44 (2018-11-19)----------Supports Chrome v69-71ChromeDriver v2.43 (2018-10-16)----------Supports Chrome v69-71ChromeDriver v2.42 (2018-09-13)----------Supports Chrome v68-70ChromeDriver v2.41 (2018-07-27)----------Supports Chrome v67-69ChromeDriver v2.40 (2018-06-07)----------Supports Chrome v66-68ChromeDriver v2.39 (2018-05-30)----------Supports Chrome v66-68ChromeDriver v2.38 (2018-04-17)----------Supports Chrome v65-67ChromeDriver v2.37 (2018-03-16)----------Supports Chrome v64-66ChromeDriver v2.36 (2018-03-02)----------Supports Chrome v63-65ChromeDriver v2.35 (2018-01-10)----------Supports Chrome v62-64### 在無GUI系統下的使用方法若是你的操做系統沒有GUI(圖形界面),則須要使用無界面的瀏覽器來搭配selenium使用,有兩種方案可選#### 1.使用phantomJS```python#安裝:selenium+phantomjs#pip3 install selenium#下載phantomjs,解壓後把phantomjs.exe放在項目目錄中或是添加到系統環境變量中#下載連接:http://phantomjs.org/download.htmlfrom selenium import webdriverdriver=webdriver.PhantomJS() #無界面瀏覽器driver.get('https://www.baidu.com')driver.page_sourcedriver.close() #關閉瀏覽器,回收資源```目前phantomJS已經中止了更新維護,幸虧Chrome 出來救場了, 是的selenium再次成爲了反爬蟲 Team 的噩夢自Google 發佈 chrome 59 / 60 正式版 開始便支持`Headless mode` 這意味着在無 GUI 環境下, PhantomJS 再也不是惟一選擇#### 2.使用chrome並設置爲無GUI模式```pythonfrom selenium import webdriverfrom selenium.webdriver.chrome.options import Optionschrome_options = Options()chrome_options.add_argument('window-size=1920x3000') #指定瀏覽器分辨率chrome_options.add_argument('--disable-gpu') #谷歌文檔提到須要加上這個屬性來規避bugchrome_options.add_argument('--hide-scrollbars') #隱藏滾動條, 應對一些特殊頁面chrome_options.add_argument('blink-settings=imagesEnabled=false') #不加載圖片, 能夠提高速度chrome_options.add_argument('--headless') #瀏覽器不提供可視化頁面. linux下若是系統若是無界面不加這條會啓動失敗chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])#取消瀏覽器驅動提示driver=webdriver.Chrome("驅動絕對路徑 若是環境變量中有則能夠不寫",chrome_options=chrome_options)driver.get('https://www.baidu.com')print('hao123' in driver.page_source)driver.close() #切記關閉瀏覽器,回收資源#selenium+谷歌瀏覽器headless模式```### 基本使用```pythonfrom selenium import webdriverfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTORfrom selenium.webdriver.common.keys import Keys #鍵盤按鍵操做from selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素browser=webdriver.Chrome()try: browser.get('https://www.baidu.com') input_tag=browser.find_element_by_id('kw') input_tag.send_keys('美女') #python2中輸入中文錯誤,字符串前加個u input_tag.send_keys(Keys.ENTER) #輸入回車 wait=WebDriverWait(browser,10) wait.until(EC.presence_of_element_located((By.ID,'content_left'))) #等到id爲content_left的元素加載完畢,最多等10秒 print(browser.page_source) print(browser.current_url) print(browser.get_cookies())finally: browser.close()```### 查找元素```python#官網連接:http://selenium-python.readthedocs.io/locating-elements.htmlfrom selenium import webdriverfrom selenium.webdriver.common.by import By #按照什麼方式查找,By.ID,By.CSS_SELECTORfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素import timedriver=webdriver.Chrome()driver.get('https://www.baidu.com')wait=WebDriverWait(driver,10)try: #===============全部方法=================== # 一、find_element_by_id # 二、find_element_by_link_text # 三、find_element_by_partial_link_text # 四、find_element_by_tag_name # 五、find_element_by_class_name # 六、find_element_by_name # 七、find_element_by_css_selector # 八、find_element_by_xpath # 強調: # 一、上述都可以改寫成find_element(By.ID,'kw')的形式 # 二、find_elements_by_xxx的形式是查找到多個元素,結果爲列表 #===============示範用法=================== # 一、find_element_by_id print(driver.find_element_by_id('kw')) # 二、find_element_by_link_text # login=driver.find_element_by_link_text('登陸') # login.click() # 三、find_element_by_partial_link_text login=driver.find_elements_by_partial_link_text('錄')[0] login.click() # 四、find_element_by_tag_name print(driver.find_element_by_tag_name('a')) # 五、find_element_by_class_name button=wait.until(EC.element_to_be_clickable((By.CLASS_NAME,'tang-pass-footerBarULogin'))) button.click() # 六、find_element_by_name input_user=wait.until(EC.presence_of_element_located((By.NAME,'userName'))) input_pwd=wait.until(EC.presence_of_element_located((By.NAME,'password'))) commit=wait.until(EC.element_to_be_clickable((By.ID,'TANGRAM__PSP_10__submit'))) input_user.send_keys('18611453110') input_pwd.send_keys('xxxxxx') commit.click() # 七、find_element_by_css_selector driver.find_element_by_css_selector('#kw') # 八、find_element_by_xpath time.sleep(5)finally: driver.close()```### 獲取標籤屬性```pythonfrom selenium import webdriverfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素browser=webdriver.Chrome()browser.get('https://www.amazon.cn/')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')#獲取標籤屬性,print(tag.get_attribute('src'))#獲取標籤ID,位置,名稱,大小(瞭解)print(tag.id)print(tag.location)print(tag.tag_name)print(tag.size)browser.close()```### 等待元素加載```python#一、selenium只是模擬瀏覽器的行爲,而瀏覽器解析頁面是須要時間的(執行css,js),一些元素可能須要過一段時間才能加載出來,爲了保證能查找到元素,必須等待#二、等待的方式分兩種:隱式等待:在browser.get('xxx')前就設置,針對全部元素有效顯式等待:在browser.get('xxx')以後設置,只針對某個元素有效```#### 隱式等待每次都會等待網頁所有加載完成再進行下一步```pythonfrom selenium import webdriverbrowser=webdriver.Chrome()#隱式等待:在查找全部元素時,若是還沒有被加載,則等10秒browser.implicitly_wait(10)browser.get('https://www.baidu.com')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()```#### 顯式等待明確的指定要等待哪個元素出現```pythonfrom selenium import webdriverfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素browser=webdriver.Chrome()browser.get('https://www.baidu.com')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()```### 交互操做#### 清空輸入框```pythonfrom selenium import webdriverfrom selenium.webdriver.support import expected_conditions as ECfrom selenium.webdriver.support.wait import WebDriverWait #等待頁面加載某些元素browser=webdriver.Chrome()browser.get('https://www.amazon.cn/')wait=WebDriverWait(browser,10)input_tag=wait.until(EC.presence_of_element_located((By.ID,'twotabsearchtextbox')))input_tag.send_keys('iphone 8')button=browser.find_element_by_css_selector('#nav-search > form > div.nav-right > div > input')button.click()import timetime.sleep(3)input_tag=browser.find_element_by_id('twotabsearchtextbox')input_tag.clear() #清空輸入框input_tag.send_keys('iphone7plus') # 輸入文字button=browser.find_element_by_css_selector('#nav-search > form > div.nav-right > div > input')button.click() # 點擊按鈕```#### 切換fream```python#frame至關於一個單獨的網頁,在父frame裏是沒法直接查看到子frame的元素的,必須switch_to_frame切到該frame下,才能進一步查找from selenium import webdrivertry: browser=webdriver.Chrome() browser.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') browser.switch_to.frame('iframeResult') #切換到id爲iframeResult的frame tag1=browser.find_element_by_id('droppable') print(tag1) # tag2=browser.find_element_by_id('textareaCode') #報錯,在子frame裏沒法查看到父frame的元素 browser.switch_to.parent_frame() #切回父frame,就能夠查找到了 tag2=browser.find_element_by_id('textareaCode') print(tag2)finally: browser.close()```#### 動做鏈```pythonfrom selenium import webdriverfrom selenium.webdriver import ActionChainsfrom selenium.webdriver.support.wait import WebDriverWait # 等待頁面加載某些元素driver = webdriver.Chrome()driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')wait=WebDriverWait(driver,3)try: driver.switch_to.frame('iframeResult') ##切換到iframeResult sourse=driver.find_element_by_id('draggable') target=driver.find_element_by_id('droppable') #方式一:基於同一個動做鏈串行執行 # actions=ActionChains(driver) #拿到動做鏈對象 # actions.drag_and_drop(sourse,target) #把動做放到動做鏈中 一次性移動到目標位置 # actions.perform() # 執行 #方式二:線性移動 ActionChains(driver).click_and_hold(sourse).perform() distance=target.location['x']-sourse.location['x'] track=0 while track < distance: ActionChains(driver).move_by_offset(xoffset=2,yoffset=0).perform() track+=2 ActionChains(driver).release().perform()finally: driver.close()```#### 執行JS在交互動做比較難實現的時候能夠本身寫JS```pythonfrom selenium import webdrivertry: browser=webdriver.Chrome() browser.get('https://www.baidu.com') browser.execute_script('alert("hello world")') #打印警告finally: browser.close()```#### 前進後退```python#模擬瀏覽器的前進後退import timefrom selenium import webdriverbrowser=webdriver.Chrome()browser.get('https://www.baidu.com')browser.get('https://www.taobao.com')browser.get('http://www.sina.com.cn/')browser.back()time.sleep(4)browser.forward()browser.close()```#### 選項卡切換```python#選項卡管理:切換選項卡,有js的方式windows.open,有windows快捷鍵:ctrl+t等,最通用的就是js的方式import timefrom selenium import webdriverbrowser=webdriver.Chrome()browser.get('https://www.baidu.com')browser.execute_script('window.open()')print(browser.window_handles) #獲取全部的選項卡browser.switch_to_window(browser.window_handles[1])browser.get('https://www.taobao.com')time.sleep(10)browser.switch_to_window(browser.window_handles[0])browser.get('https://www.sina.com.cn')browser.close()```#### xpathxpath XML_Path是一種通用的查找元素方式,也在scrapy模塊中使用```pythondoc='''<html> <head> <base href='http://example.com/' /> <title>Example website</title> </head> <body> <div id='images'> <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a> <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a> <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a> <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a> <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a> <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a> </div> </body></html>'''from lxml import etreehtml=etree.HTML(doc)# html=etree.parse('search.html',etree.HTMLParser())#/一個斜槓表示子級標籤#//一個斜槓表示子孫標籤# 1 全部節點# a=html.xpath('//*')# 2 指定節點(結果爲列表)# a=html.xpath('//head')# 3 子節點,子孫節點# a=html.xpath('//div/a')# a=html.xpath('//body/a') #無數據# a=html.xpath('//body//a')# 4 父節點# a=html.xpath('//body//a[@href="image1.html"]/..')# a=html.xpath('//body//a[1]/..')# 也能夠這樣# a=html.xpath('//body//a[1]/parent::*')# 5 屬性匹配# a=html.xpath('//body//a[@href="image1.html"]')# 6 文本獲取# a=html.xpath('//body//a[@href="image1.html"]/text()')# 7 屬性獲取# a=html.xpath('//body//a/@href')# # 注意從1 開始取(不是從0)# a=html.xpath('//body//a[1]/@href')# 8 屬性多值匹配# a 標籤有多個class類,直接匹配就不能夠了,須要用contains# a=html.xpath('//body//a[@class="li"]')# a=html.xpath('//body//a[contains(@class,"li")]')# a=html.xpath('//body//a[contains(@class,"li")]/text()')# 9 多屬性匹配# a=html.xpath('//body//a[contains(@class,"li") or @name="items"]')# a=html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')# # a=html.xpath('//body//a[contains(@class,"li")]/text()')# 10 按序選擇# a=html.xpath('//a[2]/text()')# a=html.xpath('//a[2]/@href')# 取最後一個# a=html.xpath('//a[last()]/@href')# 位置小於3的# a=html.xpath('//a[position()<3]/@href')# 倒數第二個# a=html.xpath('//a[last()-2]/@href')# 11 節點軸選擇# ancestor:祖先節點# 使用了* 獲取全部祖先節點# a=html.xpath('//a/ancestor::*')# # 獲取祖先節點中的div# a=html.xpath('//a/ancestor::div')# attribute:屬性值# a=html.xpath('//a[1]/attribute::*')# child:直接子節點# a=html.xpath('//a[1]/child::*')# descendant:全部子孫節點# a=html.xpath('//a[6]/descendant::*')# following:當前節點以後全部節點# a=html.xpath('//a[1]/following::*')# a=html.xpath('//a[1]/following::*[1]/@href')# following-sibling:當前節點以後同級節點# a=html.xpath('//a[1]/following-sibling::*')# a=html.xpath('//a[1]/following-sibling::a')# a=html.xpath('//a[1]/following-sibling::*[2]')# a=html.xpath('//a[1]/following-sibling::*[2]/@href')```