【问题标题】:Scrape values from Website using Selenium使用 Selenium 从网站中抓取值
【发布时间】:2019-10-31 10:56:11
【问题描述】:

我正在尝试从以下网站提取数据:

https://www.tipranks.com/stocks/sui/stock-analysis

我的目标是八角形中的值“6”:

我相信我的目标是正确的 xpath。

这是我的代码:

import sys
import os
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium import webdriver

os.environ['MOZ_HEADLESS'] = '1'
binary = FirefoxBinary('C:/Program Files/Mozilla Firefox/firefox.exe', log_file=sys.stdout)

browser = webdriver.PhantomJS(service_args=["--load-images=no", '--disk-cache=true'])

url = 'https://www.tipranks.com/stocks/sui/stock-analysis'
xpath = '/html/body/div[1]/div/div/div/div/main/div/div/article/div[2]/div/main/div[1]/div[2]/section[1]/div[1]/div[1]/div/svg/text/tspan'
browser.get(url)

element = browser.find_element_by_xpath(xpath)

print(element)

这是我返回的错误:

Traceback (most recent call last):
  File "C:/Users/jaspa/PycharmProjects/ig-markets-api-python-library/trader/market_signal_IV_test.py", line 15, in <module>
    element = browser.find_element_by_xpath(xpath)
  File "C:\Users\jaspa\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 394, in find_element_by_xpath
    return self.find_element(by=By.XPATH, value=xpath)
  File "C:\Users\jaspa\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 978, in find_element
    'value': value})['value']
  File "C:\Users\jaspa\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Users\jaspa\AppData\Local\Programs\Python\Python36-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: {"errorMessage":"Unable to find element with xpath '/html/body/div[1]/div/div/div/div/main/div/div/article/div[2]/div/main/div[1]/div[2]/section[1]/div[1]/div[1]/div/svg/text/tspan'","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Content-Length":"96","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:51786","User-Agent":"selenium/3.141.0 (python windows)"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"xpath\", \"value\": \"/h3/div/span\", \"sessionId\": \"d8e91c70-9139-11e9-a9c9-21561f67b079\"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/d8e91c70-9139-11e9-a9c9-21561f67b079/element"}}
Screenshot: available via screen

我可以看到问题是由于不正确的 xpath 造成的,但无法弄清楚原因。

我还应该指出,我认为使用 selenium 是抓取该站点的最佳方法,并打算提取其他值并在多个页面上针对不同股票重复这些查询。如果有人认为我使用 BeutifulSoup、lmxl 等会更好,那么我很高兴听到建议!

提前致谢!

【问题讨论】:

    标签: python selenium-webdriver web-scraping


    【解决方案1】:

    你可以试试这个css选择器[class$='shape__Octagon']来定位内容。如果我选择pyppeteer,我会这样做:

    import asyncio
    from pyppeteer import launch
    
    async def get_content(url):
        browser = await launch({"headless":True})
        [page] = await browser.pages()
        await page.goto(url)
        await page.waitForSelector("[class$='shape__Octagon']")
        value = await page.querySelectorEval("[class$='shape__Octagon']","e => e.innerText")
        return value
    
    if __name__ == "__main__":
        url = "https://www.tipranks.com/stocks/sui/stock-analysis"
        loop = asyncio.get_event_loop()
        result = loop.run_until_complete(get_content(url))
        print(result.strip())
    

    输出:

    6
    

    【讨论】:

      【解决方案2】:

      你这里似乎有两个问题:

      对于 xpath,我刚刚做了:

      xpath = '//div[@class="client-components-ValueChange-shape__Octagon"]'

      然后做:

      打印(元素.文本)

      它会得到你想要的价值。但是,您的代码实际上并没有等到浏览器完成加载页面后才执行 xpath。对我来说,使用 Firefox,我只有大约 40% 的时间以这种方式获得价值。 Selenium 有很多方法可以解决这个问题,最简单的可能是在 browser.get 和 xpath 语句之间休眠几秒钟。

      您似乎正在设置 Firefox,但随后使用的是 Phantom。我没有在 Phantom 上尝试过,Phantom 可能不需要睡眠行为。

      【讨论】:

      • 谢谢马特。这是一个非常有帮助的答案。 sleep 语句似乎是必要的——这是处理大量页面的唯一方法吗?我想我可以抓取所有的 html,然后从中提取内容?
      • 不客气。是的,我发现有必要为网络上的许多页面做这样的事情。他们做的 AJAX 东西越复杂,就越有必要。需要明确的是,如果您的意思是通过“抓取所有 html”来查询在适当的浏览器中呈现的内容,那么是的,我就是这样做的。我已经广泛尝试了 BeautifilSoup 和 lxml 并决定使用 selenium。网络的现实是有很多复杂的 AJAX 东西在发生,你最好直接进入一个真正的浏览器,然后像你在这里一样检查完全呈现的文档。
      【解决方案3】:

      您甚至没有声明所有路径。八边形在 client-components-ValueChange-shape__Octagon 类的 div 中,所以搜索这个 div。

      x = browser.find_elements_by_css_selector("div[class='client-components-ValueChange-shape__Octagon']") ## Declare which class
      for all in x:
          print all.text
      

      输出:

      6
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-23
        相关资源
        最近更新 更多