【问题标题】:Saving the text on current opened page without using urlopen不使用 urlopen 将文本保存在当前打开的页面上
【发布时间】:2021-01-27 01:37:23
【问题描述】:

我对 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

我的代码的第一部分是为了通过使用条款协议页面并打开文档,但是我如何在美丽的汤中使用该页面?我的最后三行是我尝试直接从 url 获取文本,但由于站点和用户协议,它不起作用。

【问题讨论】:

  • 您是否尝试过使用 Selenium 选择包含所需文本的元素?

标签: python selenium-webdriver beautifulsoup


【解决方案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

    问题似乎是您需要为您的请求传递一个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。如果您只是像在第二个源代码中那样使用driver.get 加载页面“https://otctransparency.finra.org/otctransparency/assets/download.html”,window.opener 将是null,这就是为什么你看No data found。您似乎应该通过单击您已加载的上一页上的链接来访问此页面。

    【讨论】:

    • 我已经更新了试图解释“未找到数据”结果的答案。
    猜你喜欢
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多