2017-08-06 47 views
1

我需要從下面的link中提取問題的答案,包括複選框。BeautifulSoup:從表格中刪除答案

這是我到目前爲止有:

from bs4 import BeautifulSoup 
import selenium.webdriver as webdriver 

url = 'https://www.adviserinfo.sec.gov/IAPD/content/viewform/adv/Sections/iapd_AdvPrivateFundReportingSection.aspx?ORG_PK=161227&FLNG_PK=05C43A1A0008018C026407B10062D49D056C8CC0' 

driver = webdriver.Firefox() 
driver.get(url) 

soup = BeautifulSoup(driver.page_source) 

下面給出我所有的書面答覆,如果有任何:

soup.find_all('span', {'class':'PrintHistRed'}) 

,我想我可以拼湊出所有的複選框答案由此:

soup.find_all('img') 

但這些不會被正確排序,因爲這不是pi找到未寫入紅色的「未提交信息」答案。

我也覺得有更好的方法來做到這一點。理想的情況是我想要的(前6題)返回:

['APEX INVESTMENT FUND, V, L.P', 
'805-2054766781', 
'Delaware', 
'United States', 
'APEX MANAGEMENT V, LLC', 
'X', 
'O', 
'No Information Filed', 
'NO', 
'NO'] 

編輯

低於馬丁的答案似乎這樣的伎倆,但是當我把它放在一個循環,結果開始改變在第三次迭代之後。任何想法如何解決這一問題?

from bs4 import BeautifulSoup 
import requests 
import re 

for x in range(5): 
    url = 'https://www.adviserinfo.sec.gov/IAPD/content/viewform/adv/Sections/iapd_AdvPrivateFundReportingSection.aspx?ORG_PK=161227&FLNG_PK=05C43A1A0008018C026407B10062D49D056C8CC0' 
    html = requests.get(url) 
    soup = BeautifulSoup(html.text, "lxml") 

    tags = list(soup.find_all('span', {'class':'PrintHistRed'})) 
    tags.extend(list(soup.find_all('img', alt=re.compile('Radio|Checkbox')))[2:])  # 2: skip "are you an adviser" at the top 
    tags.extend([t.parent for t in soup.find_all(text="No Information Filed")]) 

    output = [] 

    for entry in sorted(tags): 
     if entry.name == 'img': 
      alt = entry['alt'] 
      if 'Radio' in alt: 
       output.append('NO' if 'not selected' in alt else 'YES') 
      else: 
       output.append('O' if 'not checked' in alt else 'X') 
     else: 
      output.append(entry.text) 

    print output[:9] 

回答

0

我仔細看過HTML。我懷疑是否有這樣一個非常簡單的方法來抓取頁面。

我會從分析開始,尋找類似的問題。例如,可能會以相同的方式處理從11到16。 19和21似乎是相似的。可能有或可能沒有其他人。

我會研究如何處理每個類型的相似問題,如包含它們的行所給出的。例如,我將如何處理19和21?然後,我會編寫代碼來確定問題所在行的各個問題編號。最後,我將使用適當的代碼,使用行號從它中剔除信息。換句話說,當我遇到問題19時,我會使用19或21的代碼。

1

該網站不會通過Javascript生成任何所需的HTML,因此我選擇僅使用requests以獲取HTML(應該更快)。

解決您的問題的一種方法是將三種不同類型的所有標籤存儲到一個數組中。如果這被排序,它將導致標籤按樹形順序排列。

第一個搜索只需使用您的PrintHistRed即可獲得匹配的span標籤。其次,它找到所有img標籤,其alt文字包含單詞RadioCheckbox。最後,它搜索找到No Information Filed的所有位置並返回父標記。

的標籤現在可以進行排序和合適output陣列內置包含所需格式的信息:

from bs4 import BeautifulSoup 
import requests 
import re 

url = 'https://www.adviserinfo.sec.gov/IAPD/content/viewform/adv/Sections/iapd_AdvPrivateFundReportingSection.aspx?ORG_PK=161227&FLNG_PK=05C43A1A0008018C026407B10062D49D056C8CC0' 
html = requests.get(url) 
soup = BeautifulSoup(html.text, "lxml") 

tags = list(soup.find_all('span', {'class':'PrintHistRed'})) 
tags.extend(list(soup.find_all('img', alt=re.compile('Radio|Checkbox')))[2:])  # 2: skip "are you an adviser" at the top 
tags.extend([t.parent for t in soup.find_all(text="No Information Filed")]) 

output = [] 

for entry in sorted(tags): 
    if entry.name == 'img': 
     alt = entry['alt'] 
     if 'Radio' in alt: 
      output.append('NO' if 'not selected' in alt else 'YES') 
     else: 
      output.append('O' if 'not checked' in alt else 'X') 
    else: 
     output.append(entry.text) 

print output[:9]  # Display the first 9 entries 

給你:

[u'APEX INVESTMENT FUND V, L.P.', u'805-2054766781', u'Delaware', u'United States', 'X', 'O', u'No Information Filed', 'NO', 'YES'] 
+0

謝謝,這看起來真的很棒。我收到錯誤:「TypeError:unorderable types:Tag()

+0

我能夠讓腳本在Python 2中運行,但是有什麼想法如何讓它在Python 3中運行? –

+0

我剛剛重新創建了你的錯誤,並且似乎'Tag()'比較還沒有在Python 3版本中實現。我建議你在beautifulsoup網站上提出一張票,看看是否有解決方法或是否是已知問題。 –