python+pyquery+selenium 爬取ajax界面內容和加載問題


     python爬蟲遇到有翻頁和ajax頁面時用selenium操作更方便點,也有pyquery庫解析頁面資源,可以達到持續爬取界面的數據;

一 selenium操作瀏覽器

  

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions

url = 'xxx'
driver = webdriver.Chrome()
driver.get(url)
driver.find_element_by_xpath('xxx')
driver.find_element_by_xpath('xxx')
driver.find_element_by_xpath('xxx')
WebDriverWait(driver,20,0.5).until(expected_conditions(visibility_of_element_located((By.XPATH,'xxx'))))
driver.find_element_by_xpath('xxx')

    這主要是實例化一個瀏覽器驅動,然后操作請求界面的操作,得到想要爬取的內容;其中selenium 環境安裝有文章selenium+python 環境配置介紹,然后使用xpath定位對面后期整個爬蟲代碼健壯性有幫助,也有 selenium+pyton 的xpath應用文章介紹,這里就不重復說了,做好前期工作,開始解析界面資源了。

 二 pyquery解析界面資源

  

from pyquery import PyQuery


html = driver.page_source #獲取界面源
data = PyQuery(html) #解析界面資源,獲取源碼
items = data('.xxx').items() #通過pyquery的篩選查找規則獲取自己想要爬取的標簽
data_list = [] #用來存儲目標數據的列表
for item in items: #遍歷標簽,提取想要的內容
    dicts = {
                'xxx':item.find('.xxx').eq(1).text
                'xxx':item.find('.xxx').eq(2).text
                'xxx':item.find('.xxx').eq(3).text
                 ...
                }
    data_list.append(dicts)

     pyquery庫使用還有更多用法,推薦一篇博客 pyquery的使用;到這一步我們已經拿到想要的數據了,也整理好,下一步就是處理界面ajax問題了;

 

三 ajax加載問題處理

  

1.selenium的隱式等待,不推薦硬等待
a.WebDriverWait(driver,20,0.5).until(EC.element_to_be_clickable((By.XPATH,'xxx'))) #直到xx元素出現,隱式等待
b.WebDriverWait(driver,20,0.5).until_not(EC.element_to_be_clickable((By.XPATH,'xxx'))) #知道xx元素消失 隱式等待

2.js判斷界面接口是否加載完成
# document.readyState == “complete”  ready是所有dom結構完成並不能檢測到ajax數據請求的完成
js = 'function loadScript(url,callback) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    if(script.readyState){// IE
            script.onreadystatechange = function () {
                if(script.readyState=='load'|| script.readyState == 'complete'){
                script.onreadystatechange = null;
                    callback();
                };
            };
    }else{ // 其他瀏覽器
            script.onload = function () {
                callback();
            };
        };
    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
    };
driver.execute_script(js) 

3.python代碼判斷,親測最穩健!!!
#比如加載一個元素的屬性加載前后是變化的,就可以通過這個元素來判斷ajax是否加載完成
 while True:
     button_class =self.driver.find_element_by_xpath('xxx').get_attribute('xxx')
     if 'next-btn-loading' not in button_class:
         break

 

另外附上判斷界面元素是否存在和是否加載完畢
 1 
 2 def is_element_exit(self, xpath):
 3     ''' 判斷界面元素是否存在,存在返回True,反之返回False '''
 4     #element必須為一個列表,所以要用加s
 5     element = self.driver.find_elements_by_xpath(xpath)
 6     if len(element) != 0:
 7         return True
 8     if len(element) == 0:
 9             return False
10 
11 
12 def is_load_complete(self,xpath):
13     ''' 判斷界面加載是否完成 '''
14     while True:
15         element_statue = self.is_element_exit(xpath)
16         time.sleep(0.2)
17         if element_statue == True:
18             time.sleep(1)
19             break

 

實際經驗還是python判斷比較穩定;selenium判斷有時遇到元素一直都顯示再dom樹就不好判斷了;js判斷太復雜,需要一定js基礎。

     

四 寫入數據庫

import pymysql

conn = pymysql.connect(server,user,pwd,database)
consor = conn.consor()

for data in data_list:
    sql = "insert into [數據庫].[文件名].[表名](column1,column2,column3)".format(column1=data['xxx'],column2=data['xxx'],column3=data['xxx']...)
    consor.execute(sql)
    conn.commit()
conn.close()

    至此,基本的關於ajax加載的界面數據已經提取完成~


免責聲明!

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



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