用硒刮时单击特定的嵌套“ a”标签?

时间:2019-02-20 01:40:09

标签: python selenium selenium-webdriver web-scraping

我正在尝试从此链接https://www.hopkinsguides.com/hopkins/index/Johns_Hopkins_ABX_Guide/Antibiotics抓取信息

此网站使用jquery。我的目标是刮掉所有抗生素名称,然后为每个抗生素刮擦“非FDA批准的用途”,这在单独的链接中包含。我希望我有道理。

抗生素属于包含许多其他子类别的类别,而其他子类别则包含其他抗生素及其各自的联系。

我的程序首先登录,然后单击前7个按钮以展开并显示更多类别。我使用driver.find_element_by_x_path扩展了第一层,但是我不能以相同的方式扩展第二层(通过遍历x_path),因为如果这样做,最终将带我到另一页,其中“未经美国食品药品管理局批准”包含信息,而不是展开页面。

之所以这样做,是因为一旦您扩展了第一层,第二层现在就包含了更多的按钮/子类别和链接,这些链接会将您带到“未经FDA批准使用”的页面。

如果这些是我的x_paths

#//*[@id="firstul"]/li[1]/a 
#//*[@id="firstul"]/li[2]/a

li [1]可能是重定向链接, li [2]可能是显示更多链接的按钮(这是我首先想要的)

我做了汤来将按钮与链接分开,但是现在我无法单击底部打印出的“ a”标签进行循环。

关于我应该如何处理的任何想法??预先感谢。

这是我的代码。

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from random import randint
from bs4 import BeautifulSoup




#SIGN-IN
driver = webdriver.Chrome()
driver.get("http://www.hopkinsguide.com/home")
url = "https://www.hopkinsguides.com/hopkins/index/"

assert "Hopkins" in driver.title
sign_in_button = driver.find_element_by_xpath('//*[@id="logout"]')
sign_in_button.click()

user_elem = driver.find_element_by_name('username')
pass_elem = driver.find_element_by_id('dd-password')
user_elem.send_keys("user")
time.sleep(2)
pass_elem.send_keys("pass")
time.sleep(2)
sign_in_after_input = driver.find_element_by_xpath('//*[@id="dd-login-button"]')
sign_in_after_input.click()

def expand_page():    
    req = driver.get("https://www.hopkinsguides.com/hopkins/index/Johns_Hopkins_ABX_Guide/Antibiotics")
    time.sleep(randint(2, 4))
    #expand first layer
    for i in range(1, 8):
        driver.find_element_by_xpath("//*[@id='firstul']/li[" + str(i) + "]/a").click()
        time.sleep(2)

    html = driver.page_source
    soup = BeautifulSoup(html, features='lxml')
    for i in soup.find_all('a'):
        if i.get('data-path') != None:
            print(i)
            time.sleep(2)

expand_page()

2 个答案:

答案 0 :(得分:0)

我想您想先扩展所有可扩展节点,然后再逐个访问基础链接。从该站点的我所看到的,区别属性为<li class="expandable index-expand"><li class="index-leaf">

您可以使用Selenium来定位“ expandable index-expand”类,然后首先单击嵌套的<a>标签。然后,每次单击时对展开的子图层重复相同的操作。一旦不再在子层中检测到“可扩展的索引扩展”类,就可以继续从“索引叶”获取链接。

find_elements_by_class_name应该可以解决问题

答案 1 :(得分:0)

要扩展所有适用于您的值,这将扩展所有第一级值,并通过递归检查元素的role属性来继续检查是否有任何子值可扩展:

def click_further(driver, elem):
    subs = WebDriverWait(driver, 5).until(lambda driver: elem.find_elements_by_xpath("./following-sibling::ul//li/a"))
    for sub in subs:
        if sub.get_attribute('role') == "button":
            sub.click()
            click_further(driver, sub)

for idx in range(1,8):
    elem = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='firstul']/li[{}]/a".format(idx))))
    elem.click()
    click_further(driver, elem)

我想您可以找出如何从中提取文本的方法。