動態html,異步加載頁面的處理


Selenium

基本使用

# 導入 webdriver
from selenium import webdriver
# 調用鍵盤按鍵操作時需要引入的Keys包
from selenium.webdriver.common.keys import Keys
# 調用環境變量指定的PhantomJS瀏覽器創建瀏覽器對象
driver = webdriver.PhantomJS()
# 如果沒有在環境變量指定PhantomJS位置
# driver = webdriver.PhantomJS(executable_path="./phantomjs"))
# get方法會一直等到頁面被完全加載,然后才會繼續程序,通常測試會在這里選擇 time.sleep(2)
driver.get("http://www.baidu.com/")
# 獲取頁面名為 wrapper的id標簽的文本內容
data = driver.find_element_by_id("wrapper").text
# 打印數據內容
print data
# 打印頁面標題 "百度一下,你就知道"
print driver.title
# 生成當前頁面快照並保存
driver.save_screenshot("baidu.png")
# id="kw"是百度搜索輸入框,輸入字符串"長城"
driver.find_element_by_id("kw").send_keys(u"長城")
# id="su"是百度搜索按鈕,click() 是模擬點擊
driver.find_element_by_id("su").click()
# 獲取新的頁面快照
driver.save_screenshot("長城.png")
# 打印網頁渲染后的源代碼
print driver.page_source
# 獲取當前頁面Cookie
print driver.get_cookies()
# ctrl+a 全選輸入框內容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
# ctrl+x 剪切輸入框內容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
# 輸入框重新輸入內容
driver.find_element_by_id("kw").send_keys("itcast")
# 模擬Enter回車鍵
driver.find_element_by_id("su").send_keys(Keys.RETURN)
# 清除輸入框內容
driver.find_element_by_id("kw").clear()
# 生成新的頁面快照
driver.save_screenshot("itcast.png")
# 獲取當前url
print driver.current_url
# 關閉當前頁面,如果只有一個頁面,會關閉瀏覽器
# driver.close()
# 關閉瀏覽器
driver.quit()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

定位元素

'''
find_element_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
'''
# <div id="coolestWidgetEvah">...</div>
element = driver.find_element_by_id("coolestWidgetEvah")
# <div class="cheese"><span>Cheddar</span></div>
cheeses = driver.find_elements_by_class_name("cheese")
# <iframe src="..."></iframe>
frame = driver.find_element_by_tag_name("iframe")
# <input name="cheese" type="text"/>
cheese = driver.find_element_by_name("cheese")
# <a href="http://www.google.com/search?q=cheese">cheese</a> 根據鏈接的文本查找
cheese = driver.find_element_by_link_text("cheese")
# <div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")
# <input type="text" name="example" />
# <input type="text" name="other" />
inputs = driver.find_elements_by_xpath("//input")
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

獲取屬性值

driver.get('https://www.baidu.com/') submitBtn = driver.find_element_by_id('su') value = submitBtn.get_attribute("value") # 獲取屬性值

屏幕截圖

driver.save_screenshot(‘baidu.png’)

select下拉框處理

'''
<select id="status" class="form-control valid" οnchange="" name="status">
<option value=""></option>
<option value="0">未審核</option>
<option value="1">初審通過</option>
<option value="2">復審通過</option>
<option value="3">審核不通過</option>
</select>
'''
# 導入 Select 類
from selenium.webdriver.support.ui import Select
# 找到 name 的選項卡
select = Select(driver.find_element_by_name('status'))
# 選擇選項
# index 索引從 0 開始
# value是option標簽的一個屬性值,並不是顯示在下拉框中的值
# visible_text是在option標簽文本的值,是顯示在下拉框的值
select.select_by_index(1)
select.select_by_value("0")
select.select_by_visible_text(u"未審核")
# 取消全部
select.deselect_all()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

彈窗處理

alert = driver.switch_to_alert()

頁面前進后退

driver.forward() # 前進 driver.back() # 后退

獲取cookies

#encoding: utf-8
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time

driver_path = r"D:\ProgramApp\chromedriver\chromedriver.exe"
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://www.baidu.com/')
# 獲取cookies信息
for cookie in driver.get_cookies():
print(cookie)
print(driver.get_cookie("PSTM"))
driver.delete_cookie("PSTM")
# print(driver.get_cookie('PSTM'))
driver.delete_all_cookies()

# for cookie in driver.get_cookies():
# print "%s -> %s" % (cookie['name'], cookie['value'])
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

設置代理

driver_path = r"D:\ProgramApp\chromedriver\chromedriver.exe"
options = webdriver.ChromeOptions()
# 設置代理
options.add_argument("--proxy-server=http://165.123.0.1:4555")
# 使用代理打開瀏覽器
driver = webdriver.Chrome(executable_path=driver_path,chrome_options=options)
driver.get("http://httpbin.org/ip")
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

頁面等待

  • 程序不能確定何時某個元素完全加載出來了。
  • 如果實際頁面等待時間過長導致某個dom元素還沒出來,但是你的代碼直接使用了這個WebElement,那么就會拋出NullPointer的異常。
  • 隱式等待是等待特定的時間,顯式等待是指定某一條件直到這個條件成立時繼續執行。

隱式等待

  • 直接設置等待時間

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # 等待10秒
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("content")
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

顯式等待

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.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
# 直到 id="content" 出現
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "content"))
)
finally:
driver.quit()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

DEMO1

#encoding: utf-8

from selenium import webdriver
from lxml import etree
import re
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By


class tencentSpider(object):
driver_path = r"D:\software\chromedriver.exe"

def __init__(self):
self.driver = webdriver.Chrome(executable_path=tencentSpider.driver_path) # 驅動
self.url = 'https://tencent.hr/jog' # 起始頁
self.positions = [] # 保存數據

# 主邏輯
def run(self):
# 發送起始頁請求
self.driver.get(self.url)
while True:
source = self.driver.page_source # ajax動態源碼

# 設置延時等待下一頁按鈕加載
WebDriverWait(driver=self.driver, timeout=10).until(
EC.presence_of_element_located(
(By.XPATH, "//div[@class='pager_container']/span[last()]"))
)

# 解析列表頁
self.parse_list_page(source)

# 翻頁
try:
# 下一頁按鈕
next_btn = self.driver.find_element_by_xpath("//div[@class='pager_container']/span[last()]")
# 判斷是否是最后一頁
if "pager_next_disabled" in next_btn.get_attribute("class"):
break
else:
next_btn.click() # 點擊下一頁
except:
print(source)

time.sleep(1)

# 解析列表頁
def parse_list_page(self, source):
html = etree.HTML(source)
links = html.xpath("//a[@class='position_link']/@href") # 詳情頁的url列表
# 遍歷到每一個詳情頁
for link in links:
# 打開詳情頁
self.request_detail_page(link)
time.sleep(1)

# 打開詳情頁
def request_detail_page(self, url):
# 這里不能使用get(), 需要新打開一個詳情頁
self.driver.execute_script("window.open('%s')" % url)
self.driver.switch_to.window(self.driver.window_handles[1]) # 選擇新詳情頁

# 等待查找的元素不能是text(), 否則查找失敗超時
WebDriverWait(self.driver, timeout=10).until(
EC.presence_of_element_located(
(By.XPATH, "//div[@class='job-name']/span[@class='name']"))
)

source = self.driver.page_source # 獲取ajax源碼
self.parse_detail_page(source) # 解析詳情頁

# 關閉當前這個詳情頁
self.driver.close()
# 繼續切換回列表頁
self.driver.switch_to.window(self.driver.window_handles[0])

# 解析詳情頁
def parse_detail_page(self, source):
html = etree.HTML(source)
position_name = html.xpath("//span[@class='name']/text()")[0]
job_request_spans = html.xpath("//dd[@class='job_request']//span")
salary = job_request_spans[0].xpath('.//text()')[0].strip()
city = job_request_spans[1].xpath(".//text()")[0].strip()
city = re.sub(r"[\s/]", "", city)
work_years = job_request_spans[2].xpath(".//text()")[0].strip()
work_years = re.sub(r"[\s/]", "", work_years)
education = job_request_spans[3].xpath(".//text()")[0].strip()
education = re.sub(r"[\s/]", "", education)
desc = "".join(html.xpath("//dd[@class='job_bt']//text()")).strip()
company_name = html.xpath("//h2[@class='fl']/text()")[0].strip()

position = {
'name': position_name,
'company_name': company_name,
'salary': salary,
'city': city,
'work_years': work_years,
'education': education,
'desc': desc
}

self.positions.append(position)

print(position)
print('='*40)


if __name__ == '__main__':
spider = tencentSpider()
spider.run()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

DEMO2

#encoding: utf-8

from selenium import webdriver
from lxml import etree
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import csv
import pytesseract
from urllib import request
from PIL import Image
import re

class BossSpider(object):
driver_path = r"D:\ProgramApp\chromedriver\chromedriver.exe"
def __init__(self):
self.driver = webdriver.Chrome(executable_path=BossSpider.driver_path)
pytesseract.pytesseract.tesseract_cmd = r'D:\ProgramApp\TesseractOCR\tesseract.exe'
self.url = 'https://www.zhipin.com/c100010000/h_101250100/?query=python'
self.domain = "https://www.zhipin.com"
fp = open('boss.csv','a',newline='',encoding='utf-8')
self.writer = csv.DictWriter(fp,['name','company_name','salary','city','work_years','education','desc'])
self.writer.writeheader()

def run(self):
self.driver.get(self.url)
while True:
if len(self.driver.find_elements_by_id("captcha")) > 0:
self.fill_captcha()
time.sleep(2)
continue
source = self.driver.page_source
self.parse_list_page(source)
next_btn = self.driver.find_element_by_xpath("//a[contains(@class,'next')]")
if "disabled" in next_btn.get_attribute('class'):
break
else:
next_btn.click()

def fill_captcha(self):
captchaInput = self.driver.find_element_by_id("captcha")
captchaImg = self.driver.find_element_by_class_name("code")
submitBtn = self.driver.find_element_by_class_name('btn')
src = captchaImg.get_attribute('src')
request.urlretrieve(self.domain + src, 'captcha.png')
image = Image.open('captcha.png')
text = pytesseract.image_to_string(image)
captcha = re.sub(r"[\s/]","",text)
captchaInput.send_keys(captcha)
submitBtn.click()


def parse_list_page(self,source):
html = etree.HTML(source)
links = html.xpath("//div[@class='info-primary']//a[position()=1]/@href")
for link in links:
url = self.domain+link
self.request_detail_page(url)
time.sleep(1)

def request_detail_page(self,url):
self.driver.execute_script("window.open('%s')"%url)
self.driver.switch_to.window(self.driver.window_handles[1])
source = self.driver.page_source
self.parse_detail_page(source)
self.driver.close()
self.driver.switch_to.window(self.driver.window_handles[0])

def parse_detail_page(self,source):
html = etree.HTML(source)
name = html.xpath("//div[@class='name']/text()")[0].strip()
salary = html.xpath("//div[@class='name']/span[@class='badge']/text()")[0].strip()
infos = html.xpath("//div[@class='job-primary']/div[@class='info-primary']/p//text()")
city = infos[0]
work_years = infos[1]
education = infos[2]

company_name = html.xpath("//a[@ka='job-detail-company']/text()")[0]
desc = html.xpath("//div[@class='job-sec']/div[@class='text']//text()")
desc = "\n".join(desc).strip()
position = {
'name': name,
'company_name': company_name,
'salary': salary,
'city': city,
'work_years': work_years,
'education': education,
'desc': desc
}
self.write_position(position)

def write_position(self,position):
self.writer.writerow(position)
print(position)

if __name__ == '__main__':
spider = BossSpider()
spider.run()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

網站模擬登陸

DEMO1

# -*- coding:utf-8 -*-
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class db():
def __init__(self):
self.url = "https://www.DB.com/"
self.driver = webdriver.PhantomJS()

def log_in(self):
self.driver.get(self.url)
time.sleep(3) # 睡3分鍾,等待頁面加載
self.driver.save_screenshot("0.jpg")
#輸入賬號
self.driver.find_element_by_xpath('//*[@id="form_email"]').send_keys("xxxxx@qq.com")
#輸入密碼
self.driver.find_element_by_xpath('//*[@id="form_password"]').send_keys("xxxx")
#點擊登陸
self.driver.find_element_by_class_name("bn-submit").click()
time.sleep(2)
self.driver.save_screenshot("db.jpg")
#輸出登陸之后的cookies
print(self.driver.get_cookies())

def __del__(self):
'''調用內建的稀構方法,在程序退出的時候自動調用
類似的還可以在文件打開的時候調用close,數據庫鏈接的斷開
'''
self.driver.quit()

if __name__ == "__main__":
db= db() #實例化
db.log_in() #之后調用登陸方法
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

DEMO2

#coding=utf-8
from selenium import webdriver
import json
import time
class dd:
# 發送首頁的請求
def __init__(self):
self.driver = webdriver.PhantomJS()
self.driver.get("https://www.dd.com/directory/all") #請求首頁

#獲取頁面內容
def get_content(self):
time.sleep(3) #每次發送完請求等待三秒,等待頁面加載完成
li_list = self.driver.find_elements_by_xpath('//ul[@id="live-list-contentbox"]/li')
contents = []
for i in li_list: #遍歷房間列表
item = {}
item["img"] = i.find_element_by_xpath("./a//img").get_attribute("src") #獲取房間圖片
item["title"] = i.find_element_by_xpath("./a").get_attribute("title") #獲取房間名字
item["category"] = i.find_element_by_xpath("./a/div[@class='mes']/div/span").text #獲取房間分類
item["name"] = i.find_element_by_xpath("./a/div[@class='mes']/p/span[1]").text #獲取主播名字
item["watch_num"] = i.find_element_by_xpath("./a/div[@class='mes']/p/span[2]").text #獲取觀看人數
print(item)
contents.append(item)
return contents

#保存本地
def save_content(self,contents):
f = open("dd.txt","a")
for content in contents:
json.dump(content,f,ensure_ascii=False,indent=2)
f.write("\n")
f.close()

# 主邏輯
def run(self):
#1.發送首頁的請求
#2.獲取第一頁的信息
contents = self.get_content()
#保存內容
self.save_content(contents)
#3.循環 點擊下一頁按鈕,直到下一頁對應的class名字不再是"shark-pager-next"
while self.driver.find_element_by_class_name("shark-pager-next"): #判斷有沒有下一頁
# 點擊下一頁的按鈕
self.driver.find_element_by_class_name("shark-pager-next").click()
# 4.繼續獲取下一頁的內容
contents = self.get_content()
# 4.1.保存內容
self.save_content(contents)

if __name__ == "__main__":
dd= dd()
dd.run()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

執行javascript

打開新的頁面

# 打開首頁
driver.get('https://www.baidu.com/')
# 執行js, 打開新頁面
driver.execute_script("window.open('https://www.db.com/')")
# driver.window_handles 窗口句柄
driver.switch_to_window(driver.window_handles[1]) # 根據index選擇窗口

print(driver.current_url) # 當前頁面的url
print(driver.page_source) # 當前頁面的源碼

# 雖然在窗口中切換到了新的頁面。但是driver中還沒有切換。
# 如果想要在代碼中切換到新的頁面,並且做一些爬蟲。
# 那么應該使用driver.switch_to_window來切換到指定的窗口
# 從driver.window_handlers中取出具體第幾個窗口
# driver.window_handlers是一個列表,里面裝的都是窗口句柄。
# 他會按照打開頁面的順序來存儲窗口的句柄。
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

滾動條滾動到底部

#
from selenium import webdriver
import time

driver = webdriver.PhantomJS()
driver.get("https://movie.db.com/typerank?type_name=劇情&type=11&interval_id=100:90&action=")

# 向下滾動10000像素
js = "document.body.scrollTop=10000"
#js="var q=document.documentElement.scrollTop=10000"
time.sleep(3)
#查看頁面快照
driver.save_screenshot("db.png")
# 執行JS語句
driver.execute_script(js)
time.sleep(10)
#查看頁面快照
driver.save_screenshot("db.png")
driver.quit()
————————————————
版權聲明:本文為CSDN博主「DeltaTime」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/bua200720411091/article/details/93378461

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM