#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. Я обновил ответ, который пытается объяснить результат «Данные не найдены».