首页 文章

循环通过元素beautifulsoup

提问于
浏览
2

我不确定问题是什么 . 但我有一个使用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中, Span 在它之前 . 该模式在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次点击 . 这仅适用于上面所示的“标识符” .

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 回答

  • 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))
    

相关问题