如今不少網站的都大量使用JavaScript,或者使用了Ajax技術。這樣在網頁加載完成後,url雖然不改變可是網頁的DOM元素內容卻能夠動態的變化。若是處理這種網頁是還用requests庫或者python自帶的urllib庫那麼獲得的網頁內容和網頁在瀏覽器中顯示的內容是不一致的。javascript
使用Selenium+PhantomJS。這兩個組合在一塊兒,能夠運行很是強大的爬蟲,能夠處理cookie,JavaScript,header以及其餘你想作的任何事情。 html
Selenium是一個強大的網絡數據採集工具,最初是爲網站自動化測試開發的,其有對應的Python庫;java
Selenium安裝命令:python
pip install selenium
PhantomJS是一個基於webkit內核的無頭瀏覽器,即沒有UI界面,即它就是一個瀏覽器,只是其內的點擊、翻頁等人爲相關操做須要程序設計實現。經過編寫js程序能夠直接與webkit內核交互,在此之上能夠結合java語言等,經過java調用js等相關操做。須要去官網下載對應平臺的壓縮文件;web
PhantomJS(phantomjs-2.1.1-windows)下載地址:http://phantomjs.org/download.htmlajax
下載PhantomJs 而後將 解壓後的執行文件放在被設置過環境變量的地方,不設置的話,後續代碼就要設, 因此這裏直接放進來方便;json
而後檢測下,在cmd窗口輸入phantomjs:windows
出現這樣的畫面,即表示成功;api
Selenium+PhantomJS示例代碼:瀏覽器
from selenium import webdriver driver = webdriver.PhantomJS() driver.get('http://www.cnblogs.com/lizm166/p/8360388.html') #獲取網頁源碼 data = driver.page_source print(data) #獲取元素的html源碼 tableData = driver.find_element_by_tag_name('tableData').get_attribute('innerHTML') #獲取元素的id值 tableI = driver.find_element_by_tag_name('tableData').get_attribute('id') #獲取元素的文本內容 tableI = driver.find_element_by_tag_name('tableData').text #循環測試 list_container = driver.find_elements_by_xpath("//div[@class='list-container mb-bg']/dl/dt/h3/a") for title in list_container: print 'Num' + str(SUMRESOURCES +1) print u'標題: ' + title.text print u'連接: ' + title.get_attribute('href') driver.quit()
能輸出網頁源碼,說明安裝成功
經過這二者來解決客戶端重定向問題的例子:
程序首先加載了driver對象,而後請求網站,以後沒0.5秒檢測網站的html元素,若是html元素髮生改變則認爲頁面發生了重定向,而後打印重定向後的頁面內容。
代碼:
from selenium import webdriver import time from selenium.webdriver.remote.webelement import WebElement from selenium.common.exceptions import StaleElementReferenceException # 處理重定向,能夠定時檢查頁面的某元素 # 若是和先前的不一致則可認爲客戶端重定向 def wait_for_load(driver): #elem = driver.find_element_by_tag_name("html") title = driver.find_element_by_tag_name("title") #print(title) count = 0 while True: count += 1 if count > 20: print("Timing out after 10 seconds and returning") return time.sleep(.5) newtitle = driver.find_element_by_tag_name("title") if newtitle != title: return #try: # elem = driver.find_element_by_tag_name("html") #except StaleElementReferenceException: # return driver = webdriver.PhantomJS(executable_path='./phantomjs') driver.get("http://pythonscraping.com/pages/javascript/redirectDemo1.html") wait_for_load(driver) print(driver.page_source)
import requests from bs4 import BeautifulSoup from selenium import webdriver def getData(dataUrl): #獲取ajax返回的頁面(用bs4獲取不到ajax返回的數據) driver = webdriver.PhantomJS() driver.get(dataUrl) #獲取table元素 tables = driver.find_elements_by_tag_name('table') if tables is None: print('網頁加載獲取數據失敗') logger.info('網頁加載獲取數據失敗') #獲取table元素中的tr元素 trList = tables[0].find_elements_by_tag_name('tr') if trList is None: print('網頁加載獲取數據失敗') logger.info('網頁加載獲取數據失敗') for i in range(0,len(trList)): if i > 0: #獲取table元素中的tr元素中的td元素 tdList = trList[i].find_elements_by_tag_name('td') if tdList is not None: for n in range(0,len(tdList)): #獲取td元素文本內容 print(">>>>%s:%s"%(n,tdList[n].text)) driver.quit() def getDataUrl(issueid): dataUrl = '' url = "http://******/Scsj_tjyb_issue.jsp" headerDict = {'Host': '******', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.31 Safari/537.36', 'Accept': '*/*', 'Accept-Language': 'zh-CN,zh;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Origin':'http://******, 'Referer': 'http://******/tjyb_front/', 'Connection': 'keep-alive'} data = {'AJAX': '1', 'TEMPLATE_ID': '1114', 'ISSUEID': issueid, 'CATALOGTYPE': 'main', 'LANGUAGE': 'zh', 'HEAD': ''} res = requests.post(url, data=data, headers=headerDict) # 獲取跳轉後的頁面源碼,返回json串 soup = BeautifulSoup(res.content, "html.parser") if soup.find_all('a',target='_blank') is not None: for a_url in soup.find_all('a',target='_blank'): if a_url.string == '******統計表': dataUrl=a_url['href'] break else: print("未獲取到a標籤") logger.info("未獲取到a標籤") print('http://******'+dataUrl) return 'http://******'+dataUrl if __name__ == '__main__': url = getDataUrl('897') getData(url)
#自定義請求頭head from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities #設置自定義請求頭參數 def get_headers_driver(): desire = DesiredCapabilities.PHANTOMJS.copy() headers = {'Accept': '*/*', 'Accept-Language': 'en-US,en;q=0.8', 'Cache-Control': 'max-age=0', 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36', 'Connection': 'keep-alive', 'Referer': 'http://www.baidu.com/' } for key, value in headers.items(): desire['phantomjs.page.customHeaders.{}'.format(key)] = value driver = webdriver.PhantomJS(desired_capabilities=desire, service_args=['--load-images=yes'])#將yes改爲no可讓瀏覽器不加載圖片 return driver # 登陸 def login(): driver = get_headers_driver(cookie) url = "http://******/login/main.do" driver.get(url) #獲取網頁源碼 print(driver.page_source)
注:模擬回車鍵代碼
# 模擬回車
from selenium.webdriver.common.keys import Keys
driver.find_element_by_xpath("**").send_keys(Keys.ENTER)