2017-09-21 136 views
3

剛剛開始網頁抓取python,我正面臨一些問題。BeautifulSoup和lxml找不到div元素

我開始使用Selenium下載網頁的源代碼,並將其保存:

from selenium import webdriver 
driver= webdriver.Firefox() 
driver.get("https://www.website.com") 
f=open('output.txt','w') 
f.write(driver.page_source.encode('utf-8')) 
f.close() 
driver.quit() 

一切工作正常,但硒需要太多的時間,所以我第一次轉向機械化,以獲得頁面的源代碼:

import mechanize 
browser = mechanize.Browser() 
browser.set_handle_robots(False) 
cookies = mechanize.CookieJar() 
browser.set_cookiejar(cookies) 
browser.addheaders = [('User-agent', 'Mozilla/5.0')] 
browser.set_handle_refresh(False) 
browser.open("https://www.website.com") 

這裏談到的問題:如果我試圖找到被它的ID特定的div,它返回我沒有:

from bs4 import BeautifulSoup as BS 
soup= BS(browser.response().read(),'lxml') 
print(soup.find(id="div_id")) 

雖然如果我檢查用常規文本編輯器機械化獲得的源代碼,我可以找到它。它是這樣的:

<div id="div_id" data referrer="div_id"> 

這div有許多其他的子元素,它位於「到」代碼的1/5左右,而完整的源代碼是關於500kb.If我會轉而尋找其他分區附近,沒有運氣。而如果我在源代碼的開頭附近尋找div,它會發現它。更有趣的是,如果我嘗試在Selenium獲得的源代碼中尋找相同的div(使用BS),而不是獲取的源代碼與機械化,它能夠找到它,雖然看起來完全相同的文件編輯器檢查。

我嘗試過所有BS支持的解析器,沒有運氣。所以我想它可能有一些東西需要與BS,我試圖做同樣的LXML:

from lxml import etree 
parser= etree.HTMLParser() 
tree= etree.parse(open('source.txt'),parser) 
results= tree.xpath('//div[@id="div_id"]') 
print(etree.tostring(results[0])) 

與BS,它能夠找到與硒獲得源代碼的股利,但不與機械化。因此,我認爲它可能有一些做機械化,並轉向使用要求:

import requests 
from fake_useragent import UserAgent 
ua=UserAgent() 
url= 'https://www.website.com' 
headers= {'User-agent': str(ua.chrome)} 
page = requests.get(url, headers=headers) 

當page.content尋找的股利,無論是用BS或LXML,沒有再次發生luck.It我是否分析直接回應或者是否將它保存到文件中然後分析文件。

我認爲這是關於它的......我也嘗試過對機械化和請求響應進行編碼,因爲我看到我使用Selenium做了它,但沒有改變。我也試過使用其他BS版本(3.x),沒有改變。

總結: - 如果我找到BS或lxml的div到通過Selenium獲取的源代碼中,它會找到它。與其他的不一樣。 - 如果我在源代碼的開始處查找其他div,則BS和lxml會查找它,而與用於獲取代碼的方法無關。 - 在檢查時,div在任何情況下都存在。使用

版本: -python:2.7.9 -BeautifulSoup:4.6.0 -Mechanize:0.3.5 -REQUESTS:2.18.4 -Selenium:3.5.0 -lxml:4.0.0 -OS:linux debian

謝謝。

+0

如果您向我們提供實際的URL,這將有所幫助。 –

+0

url:https://www.facebook.com/groups/1584160618524185/ div id:pagelet_forsale_island 謝謝 – Bleracas

回答

0

您正在查找的div隱藏在可能通過Javascript處理的HTML註釋中。你可以仍然使用requests首先提取隱藏的HTML如下:

from bs4 import BeautifulSoup, Comment 
import requests 

id = "pagelet_forsale_island" 

r = requests.get("https://www.facebook.com/groups/1584160618524185/") 
soup = BeautifulSoup(r.content, "html.parser") 

for comment in soup.find_all(string=lambda text:isinstance(text, Comment)): 
    if id in comment: 
     hidden_soup = BeautifulSoup(comment, "html.parser") 

     for div in hidden_soup.find_all('div', id=id): 
      print div 

這得到BeautifulSoup找到所有的HTML註釋的,並隨後確定是否有任何包含您id。如果找到匹配,則評論本身會再次傳遞給BeautifulSoup進行進一步處理。這會顯示您的<div>爲:

<div data-referrer="pagelet_forsale_island" id="pagelet_forsale_island"></div> 
+0

就是這樣!你介意解釋如何「評論在soup.find_all(字符串= lambda文本:isinstance(文本,評論)):」工程?我不是很確定。你認爲學士學位是最適合這項任務的嗎?或者其他工具能更適合我?謝謝! – Bleracas

+0

'comments'只是特殊類型的文本。這是讓它返回文檔中找到的所有評論的訣竅。還有其他工具,我傾向於使用BS。 –