веб-парсинг для javascript __doPostBack содержит herf в td

Я хочу очистить веб-сайт, т. Е. https://www.unspsc.org/search-code/default.aspx?CSS=51%&Type=desc&SS%27=, используя селен, но я могу очистить только одну страницу, а не другие страницы.

Здесь я использую селен

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

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(executable_path='C:/Users/ptiwar34/Documents/chromedriver.exe', chrome_options=chromeOptions, desired_capabilities=chromeOptions.to_capabilities())
driver.get('https://www.unspsc.org/search-code/default.aspx?CSS=51%&Type=desc&SS%27=')
WebDriverWait(driver, 20).until(EC.staleness_of(driver.find_element_by_xpath("//td/a[text()='2']")))
driver.find_element_by_xpath("//td/a[text()='2']").click()

numLinks = len(WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//td/a[text()='2']"))))
print(numLinks)
for i in range(numLinks):
    print("Perform your scraping here on page {}".format(str(i+1)))
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td/a[text()='2']/span//following::span[1]"))).click()
driver.quit()

вот содержание html

    <td><span>1</span></td>
    <td><a 
     href="javascript:__doPostBack 
(&#39;dnn$ctr1535$UNSPSCSearch$gvDetailsSearchView&#39;,&#39;Page$2&#39;)" 
style="color:#333333;">2</a>
     </td>

Это вызывает ошибку:

raise TimeoutException(message, screen, stacktrace)
TimeoutException

person Ayush Kangar    schedule 21.08.2019    source источник


Ответы (2)


Чтобы очистить веб-сайт https://www.unspsc.org/search-code/default.aspx?CSS=51%&Type=desc&SS%27= с помощью Selenium, вы можете использовать следующую стратегию локатора:

  • Блок кода:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
    
      chrome_options = webdriver.ChromeOptions() 
      chrome_options.add_argument("start-maximized")
      driver = webdriver.Chrome(options=chrome_options, executable_path=r'C:\WebDrivers\chromedriver.exe')
      driver.get("https://www.unspsc.org/search-code/default.aspx?CSS=51%&Type=desc&SS%27=%27")
      while True:
          try:
              WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//table[contains(@id, 'UNSPSCSearch_gvDetailsSearchView')]//tr[last()]//table//span//following::a[1]"))).click()
              print("Clicked for next page")
          except TimeoutException:
              print("No more pages")
              break
      driver.quit()
    
  • Консольный вывод:

      Clicked for next page
      Clicked for next page
      Clicked for next page
      .
      .
      .
    
  • Объяснение: если вы заметили HTML DOM, номера страниц находятся внутри <table> с динамическим атрибутом id, содержащим текст UNSPSCSearch_gvDetailsSearchView. Кроме того, номера страниц находятся в пределах последней <tr>, имеющей дочерний <table>. В дочерней таблице номер текущей страницы находится внутри <span>, который содержит ключ. Итак, чтобы click() на номере следующей страницы, вам просто нужно идентифицировать следующий тег <a> с индексом [1]. Наконец, поскольку элемент имеет javascript:__doPostBack(), вы должны вызвать WebDriverWait для желаемого element_to_be_clickable().

Вы можете найти подробное обсуждение в Как мне дождаться вызова JavaScript __doPostBack через Selenium и WebDriver

person DebanjanB    schedule 21.08.2019
comment
не могли бы вы помочь соскребать код и заголовок, используя красивый суп для каждой страницы, поскольку я использую это для одной страницы unspsc_link = unspsc.org/search-code/ link = requests.get (unspsc_link) .text soup = BeautifulSoup (link, 'lxml') right_table = soup.find ('table', id = dnn_ctr1535_UNSPSCSearch_gvDetailsSearchView) df = pd.read_html (str (right_table)) [0] # Очистить DataFrame df = df [[0, 1]] df.columns = df.iloc [0 ] df = df [1:] print (df) - person Ayush Kangar; 22.08.2019
comment
@AyushKangar Ага, это можно сделать. Не могли бы вы поднять новый вопрос с вашим новым требованием? - person DebanjanB; 22.08.2019
comment
не могли бы вы объяснить // table [contains (@id, 'UNSPSCSearch_gvDetailsSearchView')] // tr [last ()] // table // span // following :: a [1], как выбрать путь, например диапазон таблицы и следующий - person Ayush Kangar; 23.08.2019
comment
@AyushKangar Добавил объяснение решения. дайте мне знать, если возникнут дополнительные вопросы. - person DebanjanB; 23.08.2019
comment
после удаления нескольких страниц @DebanjanB выдает ошибку StaleElementReferenceException: ссылка на устаревший элемент: элемент не прикреплен к документу страницы (информация о сеансе: chrome = 76.0.3809.100) - person Ayush Kangar; 23.08.2019
comment
@AyushKangar Вы проверяли ссылочную дискуссию, которую я добавил в качестве сноски в ответ? Вам это поможет? - person DebanjanB; 23.08.2019
comment
привет @DebanjanB, загляните в этот stackoverflow.com/questions/57640584/ - person Ayush Kangar; 24.08.2019

Чтобы найти / щелкнуть номера страниц, вы можете использовать:

for x in driver.find_elements_by_xpath("//a[contains(@href,'UNSPSCSearch$gvDetailsSearchView')]"):
    if x.text.isdigit():
        print(x.text)
        #x.click()
        #...

Выход:

2
3
4
...


Основываясь на вашем комментарии, вы можете использовать:

max_pages = 10
for page_number in range(2, max_pages+1):
    for x in driver.find_elements_by_xpath("//a[contains(@href,'UNSPSCSearch$gvDetailsSearchView')]"):
        if x.text.isdigit():
            if int(x.strip()) == page_number:
                x.click()
                #parse results here
                break
person Pedro Lobito    schedule 21.08.2019
comment
когда я запускаю это, как бы я сбрасывал страницы, и когда я использую этот код до x.click (), он выдает ошибку после упоминания 2 и 3 StaleElementReferenceException: ссылка на устаревший элемент: элемент не прикреплен к документу страницы (Информация о сеансе: chrome = 76.0.3809.100) - person Ayush Kangar; 21.08.2019
comment
Вам нужно добавить контроллер, чтобы знать, на какой странице вы находитесь, и анализировать новые номера страниц. - person Pedro Lobito; 21.08.2019
comment
Я выложил обновление. Если мой ответ помог вам, пожалуйста, примите его как правильный ответ, спасибо! - person Pedro Lobito; 22.08.2019