使用 BeautifulSoup 进行网页抓取,单击隐藏选项卡的元素

时间:2021-03-15 03:05:00

标签: python beautifulsoup web-crawler

我在尝试捕获页面内的特定信息时遇到问题。

网站:https://www.target.com/p/prairie-farms-vitamin-d-milk-1gal/-/A-47103206#lnk=sametab

在此页面上,我想抓取的“关于此项目”下的“详细信息”选项卡旁边有名为“标签信息”、“运输和退货”、“问答”的隐藏选项卡.

我发现我需要在使用 Beautifulsoup 进行抓取之前点击这些元素。

这是我的代码,假设我有每个链接的 pid。


    url = 'https://www.target.com' + str(pid)
    
    driver.get(url)
    driver.implicitly_wait(5)
    
    soup = bs(driver.page_source, "html.parser")
    wait = WebDriverWait(driver, 3)
    
    button = soup.find_all('li', attrs={'class': "TabHeader__StyledLI-sc-25s16a-0 jMvtGI"})
    
    index = button.index('tab-ShippingReturns')
    print('The index of ShippingReturns is:', index)
    
    if search(button, 'tab-ShippingReturns'):
       button_shipping_returns = button[index].find_element_by_id("tab-ShippingReturns")
       button_shipping_returns.click()
    time.sleep(3)

我的代码返回 结果集对象没有属性“find_element_by_id”。您可能将元素列表视为单个元素。当您打算调用 find() 时,您是否调用了 find_all()?

谁能指导我如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

以下

button = soup.find_all('li', attrs={'class': "TabHeader__StyledLI-sc-25s16a-0 jMvtGI"})

将返回一个 BeautifulSoup 标签列表。

然后您尝试使用以下命令调用该列表中的硒方法:

button_shipping_returns = button[index].find_element_by_id("tab-ShippingReturns")

相反,您需要在 webdriver 元素集合上调用它

driver.find_elements_by_css_selector('.TabHeader__StyledLI-sc-25s16a-0 jMvtGI')[index].find_element_by_id("tab-ShippingReturns")

答案 1 :(得分:0)

似乎您尝试交互的按钮通过在最后添加唯一值来动态生成类,我建议使用 xpath 选择器类型的 contains() 方法,例如:

 <style name="ToggleButton.Rounded" parent="ShapeAppearance.MaterialComponents.SmallComponent">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">16dp</item>
</style>

所以,你的代码应该是这样的:

driver.find_elements_by_xpath("//a[contains(@class,'TabHeader__Styled')]")

点击页面已经在的按钮并不可怕

如果元素不可见需要向下滚动,可以使用ActionChains:

   elements = driver.find_elements_by_xpath("//a[contains(@class,'TabHeader__Styled')]")
   for el in elements:
       el.click()

所以代码看起来像这样,只是你的元素解析器:

from selenium.webdriver import ActionChains
ActionChains(driver).move_to_element(el).perform()