Могу ли я выполнять поиск по определенным ключевым словам в строке поиска с помощью Selenium (python) во время парсинга веб-сайта?

Мне нужно парсить некоторые страницы с помощью Selenium, и прежде чем я смогу парсить, мне нужно найти определенные ключевые слова внутри веб-сайта и парсить весь контент, связанный с этими ключевыми словами, например: Пример сайта Проблема в том, что я не всегда могу использовать логический оператор для поиска по всем моим ключевым словам, поэтому мне нужно выполнить поиск по ключевому слову, например «большие данные», очистить содержимое на странице поиска, щелкнув все URL-адреса статей, чтобы очистить всю информацию. контент, сделайте это для всех статей, а затем вернитесь и найдите новое ключевое слово.

У меня уже есть код, который работает для некоторых веб-сайтов, которые мне нужно очистить, но в нем отсутствует та часть, где я ищу каждое ключевое слово.

from selenium import webdriver
from selenium.webdriver.common.by import By
import pandas as pd

def scrape_page(url):
    try:
        # Apri il sito web nel browser
        driver.get(url)
        driver.maximize_window()

        # Gestisci il banner dei cookie, se presente
        try:
            cookie_banner = driver.find_element(By.XPATH, "")
            cookie_banner.click()
        except:
            pass

        # Imposta un intervallo di attesa esplicito per 10 secondi per garantire che la pagina sia completamente caricata
        driver.implicitly_wait(10)

        # Trova tutti gli elementi "Continua a leggere"
        elements = driver.find_elements(By.XPATH, "")
        # Lista per memorizzare i dati estratti
        data = []

        # Clicca su ciascun elemento
        for index, element in enumerate(elements):
            try:
                # Ottieni URL e titolo dell'articolo
                article_url = driver.find_element(By.XPATH, "'(])["+str(index+1)+"]").get_attribute("href")
                article_title = element.find_element(By.XPATH, "'(])["+str(index+1)+"]").text
                # Clicca sull'elemento
                driver.find_element(By.XPATH, "'])["+str(index+1)+"]").click()
                # Ottieni il contenuto della landing page di "Continua a leggere"
                article_content = driver.find_element(By.XPATH, "").text
                # Ottieni la data dell'articolo
                article_date = driver.find_element(By.XPATH, "").text
                # Aggiungi i dati alla lista
                data.append({'Titolo': article_title, 'Data': article_date, 'URL': article_url, 'Contenuto': article_content})
                # Torna alla pagina precedente
                driver.back()
            except Exception as e:
                print("Errore durante il clic sull'elemento:", str(e))
    except Exception as e:
        print("Errore durante lo scraping della pagina:", str(e))
        return None

    return data

# Crea un'istanza del driver del browser
driver = webdriver.Chrome()

# URL del sito web da cui desideri effettuare il click
start_url = "https://www.salute.gov.it/portale/home.html"

# Lista per memorizzare tutti i dati estratti da tutte le pagine
all_data = []

# Cicla le pagine finché ci sono pagine successive
while start_url:
    print("Scraping:", start_url)
    page_data = scrape_page(start_url)
    if page_data:
        all_data.extend(page_data)
    
    try:
        # Cerca il link alla pagina successiva
        next_page_link = driver.find_element(By.XPATH, "")
        # Estrae l'URL della pagina successiva
        start_url = next_page_link.get_attribute("href")
    except:
        # Se non ci sono più pagine successive, interrompe il ciclo
        start_url = None

# Chiudi il browser
driver.quit()

# Costruisci un DataFrame Pandas con tutti i dati estratti
df = pd.DataFrame(all_data)

# Visualizza il DataFrame
print(df)

df.to_excel("")

Может ли кто-нибудь помочь мне обновить мой код? заранее спасибо

Я не понимаю, в чем проблема. Если у вас много ключевых слов, используйте for-цикл для запуска кода для каждого ключевого слова отдельно.

furas 28.04.2024 18:04

возможно, вам следует определить функцию с дополнительным параметром def scrape_page(url, keyword): и позже запустить ее for keyword in all_keywords: scrape_page(url, keyword)

furas 28.04.2024 18:11

да, но мне нужна функция для поиска по каждому ключевому слову в строке поиска

Roberto Artiaco 29.04.2024 13:15

Я не понимаю проблемы. используйте Selenium, чтобы найти searchbar на странице, и используйте send_keys() для отправки текста этому элементу и для отправки Key.ENTER

furas 29.04.2024 13:24

Но мне нужно искать разные ключевые слова на разных расстояниях, поэтому, когда я пишу код, мне нужно определить функцию, которая будет возвращаться на главную страницу каждый раз, когда я очищаю контент, связанный с конкретным ключевым словом.

Roberto Artiaco 29.04.2024 15:10

Я до сих пор не понимаю проблемы, с которой можно запустить for-цикл, который в первой строке запускается driver.get(url), и каждый цикл начинается с главной страницы. Честно говоря, моя предыдущая идея for keyword in all_keywords: scrape_page(url, keyword) также работает driver.get(url) для каждого ключевого слова — поэтому каждое ключевое слово начинается с главной страницы.

furas 29.04.2024 16:14

Я пытаюсь, но не могу найти решение. Могу ли я получить пример кода того, как вы это сделаете, пожалуйста?

Roberto Artiaco 29.04.2024 19:28
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
7
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Искать:

  • первая загрузка главной страницы
  • следующая панель поиска
  • в следующий раз используйте send_keys(), чтобы отправить текст в эту панель поиска,
  • и в следующий раз используйте send_key(), чтобы отправить Keys.ENTER

Он должен перенаправить на страницу с результатами, у которой есть URL driver.current_url

driver.get(start_url)

searchbar = driver.find_element(By.ID, "f_cerca")
searchbar.send_keys(word)
searchbar.send_keys(Keys.ENTER)

print(driver.current_url)

А позже вам следует запустить функцию scrape_page(), но без .get(url).

И вам следует запустить scrape_page() в цикле с кодом, который ищет ссылку на следующую страницу - и он должен использовать .get() для загрузки этой страницы (не делайте этого в scrape_page() и не загружайте главную страницу.)

И весь этот код должен находиться в for-цикле, который запускает весь код для разных ключевых слов.


Минимальный рабочий код с некоторыми изменениями:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
#from selenium.webdriver.support.ui import WebDriverWait
#from selenium.webdriver.support import expected_conditions as EC
#from selenium.common.exceptions import NoSuchElementException, TimeoutException

import time

# ---

import selenium
print('Selenium:', selenium.__version__)

# ---

def scrape_page(driver, keyword):
    try:

        # Gestisci il banner dei cookie, se presente
        try:
            print('Clicking cookie banner')            
            cookie_banner = driver.find_element(By.XPATH, "//a[b[text()='Chiudi']]")
            cookie_banner.click()
        except Exception as e:
            print('Exception:', e)

        # Trova tutti gli elementi "Continua a leggere"
        elements_dt = driver.find_elements(By.CSS_SELECTOR, "dl.simple-list.results dt")
        #elements_dd = driver.find_elements(By.XPATH, "//dl[@class='sample-list.results']/dd/a")
        
        print('[DEBUG] len(elements_dt):', len(elements_dt))
        # Lista per memorizzare i dati estratti
        data = []

        # Clicca su ciascun elemento
        #for index, element_dt, element_dd in enumerate(zip(elements_dt, elements_dd), 1):  # you can use `enumerate(..., 1)` to start `index` with `1`
        for index, element in enumerate(elements_dt, 1):  # you can use `enumerate(..., 1)` to start `index` with `1`
            
            try:
                article_url = element.find_element(By.XPATH, './/a').get_attribute("href")
                article_title = element.text
                
                # ... DON'T CLIK LINKS BECAUSE IT WILL REMOVE CURRENT PAGE FROM MEMPRY
                # ... AND YOU WILL LOST ACCESS TO OTHER `elements` ON CURRENT PAGE
                # ...
                # ... Get `href` and later (after loop) use `.get(href)` to access subpages. 
                
                data.append({
                    'keyword': keyword,
                    'Titolo': article_title, 
                    'URL': article_url, 
                    #'Data': article_date, 
                    #'Contenuto': article_content
                })
                
                print('[DEBUG] data:', data[-1])
                # Torna alla pagina precedente
                #driver.back()
            except Exception as e:
                print("Errore durante il clic sull'elemento:", e)
                
        # work with subpages

        for item in data:
            print('[DEBUG] subpage:', item['URL'])
            driver.get(item['URL'])
            #article_date = ...
            #article_content = ...
            #item['Data'] = article_date
            #item['Contenuto'] = article_content
             
    except Exception as e:
        print("Errore durante lo scraping della pagina:", e)
        return None

    return data

# --- main ---

driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)

# ---

start_url = "https://www.salute.gov.it/portale/home.html"

all_data = []

keywords = ['ukraina', 'covid-19', 'elan musk']

for word in keywords:

    print("Main Page:", start_url)

    # open main page 
    driver.get(start_url)

    # find searchbar
    print('Search:', word)
    searchbar = driver.find_element(By.ID, "f_cerca")
    # put keyword in searchbar and press ENTER
    searchbar.send_keys(word)
    searchbar.send_keys(Keys.ENTER)
    
    time.sleep(5) # wait for results
    
    #get current url (because it could load different URL to show results)
    search_results_url = driver.current_url
    
    # start scraping results (with pagination):
    #while True:  # try to get all pages
    for _ in range(3):  # try to get only 3 pages
        print("Scraping:", search_results_url)
        
        page_data = scrape_page(driver, word)  # <--- only scraping, without `.get(url)`, I send `word` only to add it to `data`
        
        if page_data:
            all_data.extend(page_data)

        driver.get(search_results_url) # go back to result after visiting subpages - to get link to next page 
        
        try:
            next_page_link = driver.find_element(By.XPATH, "//a[contains(text(), 'Successive')]")
            search_results_url = next_page_link.get_attribute("href")
            driver.get(search_results_url)  # <--- open next page with results using URL
            #next_page_link.click()   # <--- or click link 
        except Exception as e:
            print('[DEBUG] Exception:', e)
            print('[DEBUG] break')
            #input('Press ENTER to continue')
            break  # exit loop
            
driver.quit()

import pandas as pd
df = pd.DataFrame(all_data)
print(df)

input("Press ENTER to close")

Я прочитал ваши комментарии, но хотел бы спросить: когда я копирую XPath содержимого статьи, я получаю сообщение об ошибке «Невозможно найти элемент: {"method":"xpath","selector":"//" , как я могу это исправить?

Roberto Artiaco 30.04.2024 14:23

что XPATH? Если у вас есть ошибка, значит, вы используете неправильный XPATH и вам нужно найти правильный XPATH. Вы показываете ошибку с "//", но это неправильный xpath — нужно что-то большее.

furas 30.04.2024 14:39

Я попробовал использовать «.//p» по этой ссылке salute.gov.it/portale/news/p3_2_2_1_1_stampa.jsp?id=564, чтобы я мог извлечь полное содержание статьи.

Roberto Artiaco 30.04.2024 14:47

и что ты получишь? Я проверил .//p в DevTools в Chrome/Firefox (используя консоль JavaScript и команду $x('.//p')), и на этой странице 12 элементов <p> — вам нужно использовать лучший xpath, чтобы получить правильный элемент. Возможно, элемент имеет id, uniqe class или другое значение, которое вы могли бы использовать в xpath. Но вам не обязательно использовать xpath - селен допускает и By.CSS_SELECTOR и, возможно, для вас это будет проще.

furas 30.04.2024 16:42

Если содержимое статьи находится во многих <p>, то, возможно, вам следует получить их все, а затем использовать for-цикл, чтобы получить .text из всех них и .join() их в одну строку.

furas 30.04.2024 16:46

Да, похоже, я не могу получить все p с уникальным идентификатором, я пробовал с помощью селектора xpath и css, но на самом деле я не получаю содержание статей, кстати, спасибо.

Roberto Artiaco 30.04.2024 17:43

веб-страницы созданы для людей, и иногда сложно собрать все данные в одну строку. Иногда ему нужен сложный xpath, но иногда ему нужно получить некоторую часть HTML, а затем выполнить поиск данных с помощью Python - используя строковые функции или регулярные выражения или элементы подсчета и получить n-й элемент или получить элемент, который находится после другого элемента и т. д. Итак, для решения может потребоваться много строк кода.

furas 30.04.2024 18:27

Другие вопросы по теме