【问题标题】:Python Selenium only getting first row when iterating over tablePython Selenium 仅在遍历表时获得第一行
【发布时间】:2018-07-26 12:10:46
【问题描述】:

我正在尝试从以下新闻网站中提取最新的头条新闻: http://news.sina.com.cn/hotnews/

#save ids of relevant buttons that need to be clicked on the site
buttons_ids = ['Tab21' , 'Tab22', 'Tab32']

#save ids of relevant subsections
con_ids = ['Con11']

#start webdriver, go to site, hover over buttons
driver = webdriver.Chrome()
driver.get("http://news.sina.com.cn/hotnews/")
time.sleep(3)
for button_id in buttons_ids:
    button = driver.find_element_by_id(button_id)
    ActionChains(driver).move_to_element(button).perform()

然后我遍历我感兴趣的每个部分,并在每个部分中遍历所有标题,这些标题是 HTML 表中的行。但是,在每次迭代中,它都会返回第一个元素

for con_id in con_ids:
    for news_id in range(2,10):
        print(news_id)
        headline = driver.find_element_by_xpath("//div[@id='"+con_id+"']/table/tbody/tr["+str(news_id)+"]")
        text = headline.find_element_by_xpath("//td[2]/a")
        print(text.get_attribute("innerText"))
        print(text.get_attribute("href"))
        com_no = comment.find_element_by_xpath("//td[3]/a")
        print(com_no.get_attribute("innerText"))

我还尝试了以下方法,基本上将表保存为列表,然后遍历行:

for con_id in con_ids:
    table = driver.find_elements_by_xpath("//div[@id='"+con_id+"']/table/tbody/tr")
    for headline in table:
        text = headline.find_element_by_xpath("//td[2]/a")
        print(text.get_attribute("innerText"))
        print(text.get_attribute("href"))
        com_no = comment.find_element_by_xpath("//td[3]/a")
        print(com_no.get_attribute("innerText"))

在第二种情况下,我得到了该部分中标题的确切数量,因此它显然正确地获取了行数。但是,它仍然只返回所有迭代的第一行。我哪里错了?我知道有人在这里问过类似的问题:Selenium Python iterate over a table of rows it is stopping at the first row 但我仍然无法弄清楚我哪里出错了。

【问题讨论】:

    标签: python selenium html-table


    【解决方案1】:

    在 XPath 中,以 // 开头的查询将相对于文档根进行搜索;因此,即使您在正确的容器元素上调用 find_element_by_xpath(),您也会超出该范围,从而每次执行相同的全局搜索并产生相同的结果。

    要将查询限制为当前元素的后代,请以 .// 开始查询,例如:

    text = headline.find_element_by_xpath(".//td[2]/a")
    

    【讨论】:

    • 谢谢,Ian,如果我像这样开始查询,它确实有效。由于解释,我将其作为公认的答案。但 Pradeep 的更新代码也能正常工作。
    • 这是因为他将其更新为在查询开头包含.。 ?
    【解决方案2】:

    试试这个:

    for con_id in con_ids:
        for news_id in range(2,10):
            print(news_id)
            print("(//div[@id='"+con_id+"']/table/tbody/tr)["+str(news_id)+"]")
            headline = driver.find_element_by_xpath("(//div[@id='"+con_id+"']/table/tbody/tr)["+str(news_id)+"]")
            value = headline.find_element_by_xpath(".//td[2]/a")
            print(value.get_attribute("innerText").encode('utf-8'))
    

    我可以通过上面的代码获得头条

    【讨论】:

    • 感谢您的建议。你说它对你有用?你有10个不同的头条新闻吗?因为不幸的是,当我运行它时,您的代码产生的结果与我的完全相同。它打印第一个标题 10 次。不知何故,即使我明确地将另一行的索引传递给它,它也总是选择第一行。
    • @Sebastian 我已经编辑了我的答案,你现在可以试试
    • @Sebastian 我可以使用上面更新的代码获得所有 10 个标题,看看它一次。
    【解决方案3】:

    我能够通过一次性指定整个 XPath 来解决它,如下所示:

    headline = driver.find_element_by_xpath("(//*[@id='"+con_id+"']/table/tbody/tr["+str(news_id)+"]/td[2]/a)")
    print(headline.get_attribute("innerText"))
    print(headline.get_attribute("href"))
    

    而不是将其分成两部分。 我对为什么它只重复打印第一行的唯一解释是,有一些奇怪的 Javascript 在工作,它不允许您在拆分请求时正确迭代。 或者我的第一个版本有语法错误,我不知道。 如果有人有更好的解释,我很高兴听到它!

    【讨论】:

      猜你喜欢
      • 2016-06-05
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2020-09-22
      • 1970-01-01
      相关资源
      最近更新 更多