循环通过元素beautifulsoup

时间:2016-02-17 18:57:01

标签: python selenium beautifulsoup

我不确定问题是什么。但我有一个使用Selenium和Beautifulsoup 4的小脚本,使用特定输入访问和解析特定网站的内容。对于每个搜索词,我想将元素追加到列表中。这是html:

<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在第2个tr中,跨度在它之前的那个。该模式在table-element内继续为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次点击。这仅适用于&#34;标识符&#34;如上所示。

    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已经提出过这个建议。问题已解决。

1 个答案:

答案 0 :(得分:3)

这是一个包含多项改进的完整代码(在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))