Проблема соскоба предметов с двух разных глубин с помощью селена - PullRequest
1 голос
/ 16 апреля 2020

Я создал скрипт в python в сочетании с селеном, чтобы получить number ответов с его целевой страницы и name спрашивающего с его внутренней страницы. Я знаю, что легче разобрать два вопроса, используя ссылки на вопрос и ссылки на следующую страницу, но я не собираюсь здесь делать это. Суть в том, что я пытаюсь пройтись по разным местам только с помощью кликов. Однако, когда я запускаю скрипт, он выдает следующую ошибку, указывающую на эту строку answer = WebDriverWait(item,10) во второй итерации.

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

Хотя элементы I искать доступны как на целевой странице, так и на внутренней странице. Требуется, чтобы я очистил два элемента с двух разных глубин.

Я знаю, как очистить их с помощью запросов, поэтому Я тоже не хочу go по этому маршруту.

Скрипт, с которым я пробую:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

link = 'https://stackoverflow.com/questions/tagged/web-scraping'

def get_content(link):
    driver.get(link)
    while True:
        for count,item in enumerate(WebDriverWait(driver,10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR,".question-summary")))):
            #error thrown in the following line in it's second iteration
            answer = WebDriverWait(item,10).until(EC.presence_of_element_located((By.CSS_SELECTOR,"[class$='answered'] > strong"))).text

            elem = driver.find_elements_by_css_selector(".summary a.question-hyperlink")[count]
            driver.execute_script("arguments[0].click();",elem)
            name = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CSS_SELECTOR,"h1[itemprop='name'] > a"))).text
            print(answer,name)
            driver.back()

        try:
            next_page = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.CSS_SELECTOR,"a[rel='next']")))
            driver.execute_script("arguments[0].click();",next_page)
        except Exception:
            break

if __name__ == '__main__':
    with webdriver.Chrome() as driver:
        get_content(link)

Как я могу скрести два предмета с двух разных глубин?

PS Если я вычеркну эту строку answer = WebDriverWait(item,10)----, сценарий будет работать как заклинание, пересекающее разную глубину и несколько страниц.

1 Ответ

2 голосов
/ 16 апреля 2020

Это нормально, что вы получаете StaleElementReferenceException, потому что вы покидаете страницу и ссылка на элементы .question-summary теряется.

Описание ошибки: Thrown when a reference to an element is now "stale".

Чтобы сделать это так, как вы хотите, код ниже будет работать. Я изменил [class$='answered'] > strong селектор на [class*='answered'] > strong, в противном случае вы получите ошибку, если вопрос уже принял ответ. Если вы хотите, чтобы только не были приняты, измените скрипт по мере необходимости.

def get_content(link):
    driver.get(link)
    while True:
        count = len(WebDriverWait(driver, 10).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".question-summary"))))
        for ix in range(count):
            question = driver.find_elements_by_css_selector(".question-summary")[ix]
            answers_count = question.find_element_by_css_selector("[class*='answered'] > strong").text

            driver.execute_script("arguments[0].click();", question.find_element_by_css_selector("a.question-hyperlink"))
            name = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "h1[itemprop='name'] > a"))).text
            print(answers_count, name)
            driver.back()
        try:
            next_page = WebDriverWait(driver, 10).until(
                EC.presence_of_element_located((By.CSS_SELECTOR, "a[rel='next']")))
            driver.execute_script("arguments[0].click();", next_page)
        except Exception:
            break
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...