Сохранение текста на текущей открытой странице без использования urlopen

#python #selenium-webdriver #beautifulsoup

#python #selenium-webdriver #beautifulsoup

Вопрос:

Я довольно новичок в python и пытаюсь автоматизировать что-то для моего отца как проект. Я пытаюсь сохранить только текст на открытой странице без использования urlopen, мой текущий код откроет для меня страницу, но я не могу понять, как загрузить только текст страницы, а сайт не позволяет вам напрямую открывать URL-адрес с помощью чего-то вроде urllib. Это мой текущий код, который открывает файл.

 from urllib.request import urlopen
from selenium import webdriver
from selenium.webdriver.common.by import By

url = "https://otctransparency.finra.org/otctransparency/OtcDownload"
chrome_path = "C:\Users\derpe\Downloads\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get(url)

#bypass user agreement
agree = driver.find_elements_by_xpath("//button[@class='btn btn-warning']")[0]
driver.implicitly_wait(5)
agree.click()

#open non-ats page
nonats = driver.find_element_by_link_text('OTC (Non-ATS) Download')
driver.implicitly_wait(5)
nonats.click()

#open download page
downloadats = driver.find_element_by_xpath("//img[@src='./assets/icon_download.png']")
driver.implicitly_wait(5)
downloadats.click();
driver.implicitly_wait(5)

##not working
#bs get text with url
html = 'https://otctransparency.finra.org/otctransparency/assets/download.html'
soup = BeautifulSoup(urlopen(html))
print(soup.get_text())
##returns HTTPError: Forbidden
  

Первая часть моего кода предназначалась для перехода на страницу соглашения об условиях использования и открытия документа, но как мне затем использовать эту страницу в beautiful soup? мои последние три строки — это моя попытка получить текст непосредственно из URL, но это не работает из-за сайта и пользовательского соглашения.

Комментарии:

1. Вы пробовали выбирать элементы, которые содержат нужный текст, используя Selenium?

Ответ №1:

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

Следующий код сделает это:

 from selenium import webdriver
from selenium.webdriver.common.by import By

url = "https://otctransparency.finra.org/otctransparency/OtcDownload"
chrome_path = "C:\Users\derpe\Downloads\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get(url)

#bypass user agreement
agree = driver.find_elements_by_xpath("//button[@class='btn btn-warning']")[0]
driver.implicitly_wait(5)
agree.click()

#open non-ats page
nonats = driver.find_element_by_link_text('OTC (Non-ATS) Download')
driver.implicitly_wait(5)
nonats.click()

#open download page
downloadats = driver.find_element_by_xpath("//img[@src='./assets/icon_download.png']")
driver.implicitly_wait(5)
downloadats.click();
driver.implicitly_wait(5)

# switch the tab
driver.switch_to_window(driver.window_handles[1])
driver.implicitly_wait(10)

# extract the text in the pre tag
print(driver.find_element_by_tag_name("pre").text)
  

Ответ №2:

Во-первых, вы должны выполнить вызов implicitly_wait once и, прежде чем пытаться найти элементы.

Проблема, похоже, в том, что вам нужно передать User-Agent заголовок для вашего запроса. Фактический возвращаемый текст — это чистый JavaScript, который в конечном итоге загружает содержимое страницы (я распечатал это), поэтому вызов формы возвращаемого значения get_text — это просто пустые строки:

 from urllib.request import urlopen, Request
from selenium import webdriver
from selenium.webdriver.common.by import By

url = "https://otctransparency.finra.org/otctransparency/OtcDownload"
chrome_path = "C:\Users\derpe\Downloads\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.implicitly_wait(5)
driver.get(url)

#bypass user agreement
agree = driver.find_elements_by_xpath("//button[@class='btn btn-warning']")[0]
agree.click()

#open non-ats page
nonats = driver.find_element_by_link_text('OTC (Non-ATS) Download')
nonats.click()

#open download page
downloadats = driver.find_element_by_xpath("//img[@src='./assets/icon_download.png']")
downloadats.click();

#bs get text with url
url = 'https://otctransparency.finra.org/otctransparency/assets/download.html'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
headers = { 'User-Agent' : user_agent }
req = Request(url, headers=headers)
resp = urlopen(req)
html = resp.read().decode('utf-8')
soup = BeautifulSoup(html)
print(soup.get_text())
print(html)
driver.quit()
  

С принтами:







 <html>
  <head>
    <title></title>
    <meta name="google" content="notranslate" />
    <script>
      var welcomeMessage = 'Please wait';

      window.onload = function()
      {
        if (!window.opener)
        {
          document.body.innerHTML = 'No data found';
        }
        else if (window.opener.downloadCache)
        {
          document.body.innerHTML = window.opener.downloadCache;
        }
        else  
        {
          document.body.innerHTML = welcomeMessage;
          console.log(document.body.innerHTML.substr(0, welcomeMessage.length));
          loading();
        }
      }

      function loading()
      {
        if (document.body.innerHTML.substr(0, welcomeMessage.length) == welcomeMessage)
        {
          document.body.innerHTML  = '.';
          setTimeout(loading, 500);
        }
      }
    </script>
  </head>
  <body></body>
</html>
  

Итак, вы должны пытаться загрузить последнюю страницу с помощью selenium:

 from selenium import webdriver
from selenium.webdriver.common.by import By

url = "https://otctransparency.finra.org/otctransparency/OtcDownload"
chrome_path = "C:\Users\derpe\Downloads\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)

driver.implicitly_wait(5)
driver.get(url)

#bypass user agreement
agree = driver.find_elements_by_xpath("//button[@class='btn btn-warning']")[0]
agree.click()

#open non-ats page
nonats = driver.find_element_by_link_text('OTC (Non-ATS) Download')
nonats.click()

#open download page
downloadats = driver.find_element_by_xpath("//img[@src='./assets/icon_download.png']")
downloadats.click();

#bs get text with url
url = 'https://otctransparency.finra.org/otctransparency/assets/download.html'
driver.get(url)
soup = BeautifulSoup(driver.page_source)
print(soup.get_text())
driver.quit()
  

С принтами:




Данные не найдены

Комментарий

Если вы посмотрите на JavaScript, возвращенный в первой версии исходного кода, вы увидите:

     if (!window.opener)
    {
      document.body.innerHTML = 'No data found';
    }
  

См. Window.opener . Если вы просто загрузите страницу ‘https://otctransparency.finra.org/otctransparency/assets/download.html «с driver.get тем, как это сделано во втором исходном коде, window.opener так и будет null , и именно поэтому вы видите No data found . Похоже, вы должны перейти на эту страницу, нажав на ссылку, которая находится на предыдущей загруженной вами странице.

Комментарии:

1. Я обновил ответ, который пытается объяснить результат «Данные не найдены».