2016-02-17 356 views
2

我不確定問題是什麼。但我有一個小腳本,使用Selenium和Beautifulsoup 4使用特定輸入訪問和解析特定網站的內容。對於每個搜索詞,我想將這些元素附加到列表中。這是html:循環通過元素beautifulsoup

<table class="aClass"> 
     <tr class="1"> 
     <td> 
     <a href="aLink"> 
      <span class="aClass"> 
      Text 
      </span> 
     </a> 
     </td> 
     <td> 
     </td> 
     <td> 
     </td> 
     <td> 
     </td> 
     </tr> 
     <tr class="2"> 
     <td> 
     </td> 
     <td anAttribute="aValue"> 
     Text 
     </td> 
     <td> 
     </td> 
     </tr> 
</table> 

想要的td是在第二個tr和跨度是在它之前。該模式在表格元素內繼續X點命中。

預期結果是在每個列表238,但是當我打印的長度它甚至不接近。它停在25.當我將數據寫入文件時,存在同樣的問題。然而,該列表確實包含來自所有不同搜索的結果。我認爲我以這些元素爲目標的方式可能是問題所在,但與html的結構相比,似乎並不是這樣。以錯誤的方式循環元素?

完整代碼:

def searchAndExtract(): 
    searches = ['Search1', 'Search2', 'Search3'] 
    textContents = [] 
    idContents = [] 
    data = [] 
    data.append(['ID', 'MESSAGE']) 
    driver = webdriver.PhantomJS() 
    url = 'https://website.com' 
    driver.get(url) 
    for search in searches: 
     input = driver.find_element_by_id("q") 
     element = input.get_attribute('value') 
     if len(element) > 0: 
      input.clear() 
     input.send_keys(search) 
     input.submit() 
     pagehtml = driver.page_source 
     soup = BeautifulSoup(pagehtml) 
     identifiers = soup.find_all('span', {"class": "aClass"})  
     messages = soup.find_all('td', {"anAttribute": "aValue" }) 
     for identifier in identifiers: 
      idContents.append(identifier.text) 
     for message in messages: 
      textContents.append(message.text) 
    for i, ids in enumerate(idContents): 
     data.append([ids, textContents[i]]) 

所以我循環的一切錯誤的方式,我仍然認爲。但我不知道我應該做什麼。我嘗試過,但只能繼續獲得前25次點擊。這僅適用於上述「標識符」。

for tr in soup.find_all('tr'): 
     for td in tr.find_all('td'): 
      for span in td.find_all('span', {"class": "aClass"}): 
       if span.parent.name == 'a': 
        print span.text 

好吧 - 我的壞。這是一個解析器問題,當我嘗試不同的問題時,我很不耐煩。 alecxce已經提出了這個問題。問題已修復。

+0

你能分享你的完整的代碼?謝謝。 – alecxe

+0

查看上面的完整代碼 – user3471881

+1

在'submit()'後面加上'time.sleep(5000)'有什麼區別? – alecxe

回答

2

下面是幾個改進(湊了data列表中選擇所需319行)的完整代碼:

from bs4 import BeautifulSoup 
from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.select import Select 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 


searches = ['Norway'] 
data = [['ID', 'MESSAGE']] 

driver = webdriver.PhantomJS() 
wait = WebDriverWait(driver, 10) 
url = 'your URL here' 
driver.get(url) 

for search in searches: 
    # select 1000 results 
    select = Select(driver.find_element_by_id("count")) 
    select.select_by_visible_text("1000") 

    # provide the search query and search 
    input = driver.find_element_by_id("q") 
    input.clear() 
    input.send_keys(search) 
    input.submit() 

    # wait until loaded 
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "a.top"))) 

    # parse search results with BeautifulSoup 
    pagehtml = driver.page_source 
    soup = BeautifulSoup(pagehtml, "html5lib") 
    identifiers = [id.get_text(strip=True) 
        for id in soup.find_all('span', {"class": "glyphicon glyphicon-open-file"})] 
    messages = [message.get_text(strip=True) 
       for message in soup.find_all('td', {"colspan": "3"})] 
    data.extend(zip(identifiers, messages)) 

print(len(data))