Как извлечь все тексты из тега <a>с помощью Selenium через Python - PullRequest
0 голосов
/ 04 июня 2019

Вот ссылка веб-сайта, откуда я хочу извлечь данные. Я пытаюсь получить весь текст атрибута href под тегом привязки.Вот пример HTML:

<div id="borderForGrid" class="border">
  <h5 class="">
    <a href="/products/product-details/?prod=30AD">A/D TC-55 SEALER</a>
  </h5>

<div id="borderForGrid" class="border">
  <h5 class="">
    <a href="/products/product-details/?prod=P380">Carbocrylic 3356-1</a>
 </h5>

Я хочу извлечь все текстовые значения, такие как ['A/D TC-55 SEALER','Carbocrylic 3356-1'].
Я пробовал с:

target = driver.find_element_by_class_name('border')
anchorElement = target.find_element_by_tag_name('a')
anchorElement.text

, но это дает '' (пустая) строка.

Любое предложение о том, как этого достичь?

PS - Выберите первое значение переключателя в разделе ТИП ПРОДУКТА

Ответы [ 3 ]

2 голосов
/ 04 июня 2019

Похоже, что при первой загрузке веб-сайта также загружаются все продукты. Нумерация страниц внизу фактически не меняется на разные страницы. Таким образом, вы можете извлечь все продукты по первому запросу http://www.carboline.com/products/. Я использовал python requests для получения сайтов HTML и lxml html для анализа HTML.

Я бы держался подальше от селена и т. Д., Если это возможно (иногда у вас нет выбора). Но если веб-сайт очень прост, как тот, что в вашем вопросе. Тогда я бы порекомендовал просто сделать request. Это позволяет избежать необходимости использовать браузер со всеми дополнительными издержками, поскольку вы запрашиваете только то, что вам нужно.

** Я обновил свой ответ, чтобы показать вам, как вы можете извлечь href и text одновременно.

import requests

from lxml import html

BASE_URL = 'http://www.carboline.com'

def extract_data(tree):
    elements = [
        e
        for e in tree.cssselect('div.border h5 a')
        if e.text is not None
    ]
    return elements

def build_data(data):
    dataset = []

    for d in data:
        link = BASE_URL + d.get('href')
        title = d.text

        dataset.append(
            {
                'link':link,
                'title':title
            }
        )

    return dataset

def request_website(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'
    }
    r = requests.get(url, headers=headers)
    return r.text

response = request_website('http://www.carboline.com/products/')
tree = html.fromstring(response)
data = extract_data(tree)
dataset = build_data(data)
print (dataset)
1 голос
/ 04 июня 2019

Чтобы извлечь все текстовые значения в тегах <a>, например, ['A / D TC-55 SEALER', 'Carbocrylic 3356-1'] , вам нужно вызвать WebDriverWait для visibility_of_all_elements_located(), и вы можете использовать любое из следующих решений:

  • Использование CSS_SELECTOR:

    print([my_elem.get_attribute("innerHTML") for my_elem in WebDriverWait(driver, 5).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "li.topLevel[data-types='Acrylics'] h5>a[href^='/products/product-details/?prod=']")))])
    
  • ИспользованиеXPATH:

    print([my_elem.get_attribute("innerHTML") for my_elem in WebDriverWait(driver, 5).until(EC.visibility_of_all_elements_located((By.XPATH, "//li[@class='topLevel' and @data-types='Acrylics']//h5[@class]/a[starts-with(@href, '/products/product-details/?prod=')]")))])
    
  • Примечание : Вы должны добавить следующие операции импорта:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
0 голосов
/ 04 июня 2019

Если вам нужны все значения ссылок, вы должны использовать функции find_elements_...., а не find_element_..., так как последняя вернет вам первое совпадение.

Рекомендуемое обновление для вашего кода:

driver.get("http://www.carboline.com/products/")
for link in driver.find_elements_by_xpath("//ul[@id='productList']/descendant::*/a"):
    if link.is_displayed():
        print(link.text)

Дополнительная информация:

...