前三篇部落格已經介紹了,如何利用selenium去爬取一個指定內容的百度文庫的文章連結和文章的名稱,接下這篇部落客要介紹的是,針對於一篇文章我們應該如何去爬取所有的內容
1、分析文章的頁面結構,文章地址https://wenku.baidu.com/view/1d03027280eb6294dd886cb7.html?from=search
通過上圖我們可以觀察到,開啟文章連結之後,可能有的文章顯示不全需要點擊“繼續閱讀”按鈕之後,才能看到所有的內容。
if __name__ == "__main__": browser = webdriver.Chrome() browser.get("https://wenku.baidu.com/view/1d03027280eb6294dd886cb7.html?from=search") #擷取點擊繼續閱讀按鈕 goBtn = browser.find_element_by_class_name("goBtn") goBtn.click()運行之後,你會發現,在pycharm的控制台報錯,selenium.common.exceptions.WebDriverException: Message: unknown error: Element <span class="moreBtn goBtn">...</span> is not clickable at point (449, 565). Other element would receive the click: <div class="content" id="reader-evaluate-content-wrap" data-id="1d03027280eb6294dd886cb7" data-value="-1" data-doc-value="0">...</div>,這個錯誤的意思是不能去點擊這個標籤,它可以去點擊這個div。為什麼會這樣呢。細心的朋友可能會看見上圖的右下角有一個箭頭,仔細看有一句style屬性是,overflow:hidden這句話的意思是隱藏這個標籤,所以才導致這個錯誤的發生。selenium的python api連結 http://selenium-python.readthedocs.io/api.html,解決辦法如下,
if __name__ == "__main__": browser = webdriver.Chrome() browser.get("https://wenku.baidu.com/view/1d03027280eb6294dd886cb7.html?from=search") #找到繼續閱讀按鈕的上一級div,banner-more-btn是div的類名用.,ID用# hidden_div = browser.find_element_by_css_selector("#html-reader-go-more") #擷取閱讀按鈕 gotBtn = browser.find_element_by_css_selector("#html-reader-go-more .banner-more-btn") actions = webdriver.ActionChains(browser) actions.move_to_element(hidden_div) actions.click(gotBtn) actions.perform()在點擊繼續閱讀按鈕之前,最好先判斷這個按鈕是否存在,如果只有1頁的時候,是不會有這個按鈕的,判斷方法,可以用之前的方法進行判斷。擷取文章的所有內容
time.sleep(3) #擷取包含內容的div div_text = browser.find_elements_by_class_name("ie-fix") for temp in div_text: text = temp.text print text
注意:有可能會因為百度文庫的廣告導致將繼續閱讀按鈕遮住,致使點擊的時候,點擊不到繼續閱讀按鈕,所以,你需要找到廣告的位置(需要先判斷廣告是否存在,再做處理,否則可能會報錯),然後,使用讓隱藏按鈕可以點擊的方法處理廣告即可。
#encoding:utf8import sysreload(sys)sys.setdefaultencoding("utf8")from selenium import webdriverimport timedef gethrefAndFilename(browser): # 開啟百度文庫的首介面 browser.get("https://wenku.baidu.com/") # 通過ID找網頁的標籤,找到搜尋方塊的標籤 seek_input = browser.find_element_by_id("kw") # 設定搜尋的內容 contents = "飲料" contents = str(contents).decode("utf8") seek_input.send_keys(contents) # 找到搜尋文檔按鈕 seek_but = browser.find_element_by_id("sb") # 並點擊搜尋文檔按鈕 seek_but.click() # 檔案標籤集合 list_href = [] # 檔案名稱集合 list_filename = [] while True: # 擷取所有的文檔a標籤,這裡的elements指的是有多個元素,*表示的是任意的(在xpath中可以用) all_a = browser.find_elements_by_xpath("//*[@id=\"bd\"]/div/div/div[4]/div/dl[*]/dt/p[1]/a") for a in all_a: # print a.get_attribute("href") # print a.get_attribute("title") list_href.append(a.get_attribute("href")) list_filename.append(a.get_attribute("title")) # 擷取body標籤,的html body = browser.find_element_by_tag_name("body") body_html = body.get_attribute("innerHTML") # 判斷下一頁按鈕是否存在 flag = str(body_html).find("class=\"next\"") if flag != -1: # 擷取下一頁按鈕的標籤,這裡用的是class標籤,因為它只有一個 next_page = browser.find_element_by_class_name("next") # 點擊下一頁 next_page.click() # 點擊之後,睡眠5s,防止頁面沒有載入完全,報no such element的錯誤 time.sleep(5) break else: break return list_href,list_filenamedef getContentsByHref(href,browser): browser.get(href) body = browser.find_element_by_tag_name("body") flag = str(body).find("id=\"html-reader-go-more\"") if flag != -1: # 找到繼續閱讀按鈕的上一級div,banner-more-btn是div的類名用.,ID用# hidden_div = browser.find_element_by_css_selector("#html-reader-go-more") # 擷取閱讀按鈕 gotBtn = browser.find_element_by_css_selector("#html-reader-go-more .banner-more-btn") actions = webdriver.ActionChains(browser) actions.move_to_element(hidden_div) actions.click(gotBtn) actions.perform() time.sleep(3) # 擷取包含內容的div div_text = browser.find_elements_by_class_name("ie-fix") for temp in div_text: text = temp.text print textif __name__ == "__main__": browser = webdriver.Chrome() list_href, list_filename = gethrefAndFilename(browser) for href in list_href: getContentsByHref(href,browser)輸出結果: