【问题标题】:Scrapy/Splash Click on a button then get content from new page in new windowScrapy/Splash 单击一个按钮,然后在新窗口中从新页面获取内容
【发布时间】:2019-05-31 14:19:50
【问题描述】:

我遇到的问题是,当我单击一个按钮时,Javascript 会处理该操作,然后它会重定向到带有新窗口的新页面(这类似于您单击目标为 _Blank 的 <a> 时)。在scrapy/splash中,我不知道如何从新页面获取内容(我的意思是我不知道如何控制那个新页面)。

任何人都可以提供帮助!

script = """
    function main(splash)
        assert(splash:go(splash.args.url))
        splash:wait(0.5)
        local element = splash:select('div.result-content-columns div.result-title')
        local bounds = element:bounds()
        element:mouse_click{x=bounds.width/2, y=bounds.height/2}
        return splash:html()
    end
"""

def start_requests(self):
    for url in self.start_urls:
        yield SplashRequest(url, self.parse, endpoint='execute', args={'lua_source': self.script})

【问题讨论】:

    标签: python scrapy splash-screen scrapy-splash


    【解决方案1】:

    问题:

    无法抓取超出选择范围的 html 的问题。单击新链接时,如果涉及 iframe,则很少会将其纳入抓取范围。

    解决方案:

    选择一种选择新 iframe 的方法,然后继续解析新的 html。

    Scrapy-Splash 方法

    (这是对this answer的Mikhail Korobov解决方案的改编)

    如果你能拿到弹出的新页面的src链接,可能是最靠谱的,不过你也可以试试这样选择iframe:

    # ...
        yield SplashRequest(url, self.parse_result, endpoint='render.json', 
                            args={'html': 1, 'iframes': 1})
    
    def parse_result(self, response):
        iframe_html = response.data['childFrames'][0]['html']
        sel = parsel.Selector(iframe_html)
        item = {
            'my_field': sel.xpath(...),
            # ...  
        }
    

    Selenium 方法

    (需要 pip install selenium,bs4,可能还需要从此处为您的操作系统下载 chrome 驱动程序:Selenium Chromedrivers)支持 Javascript 解析!哇哦!

    使用以下代码,这会将范围切换到新框架:

    # Goes at the top
    from bs4 import BeautifulSoup 
    from selenium.webdriver.chrome.options import Options
    import time
    
    # Your path depends on where you downloaded/located your chromedriver.exe
    CHROME_PATH = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
    CHROMEDRIVER_PATH = 'chromedriver.exe'
    WINDOW_SIZE = "1920,1080"
    
    chrome_options = Options()
    chrome_options.add_argument("--log-level=3")
    chrome_options.add_argument("--headless") # Speeds things up if you don't need gui
    chrome_options.add_argument("--window-size=%s" % WINDOW_SIZE)
    
    chrome_options.binary_location = CHROME_PATH
    
    browser = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, chrome_options=chrome_options)
    
    url = "example_js_site.com" # Your site goes here
    browser.get(url)
    time.sleep(3) # An unsophisticated way to wait for the new page to load.
    browser.switch_to.frame(0)
    
    soup = BeautifulSoup(browser.page_source.encode('utf-8').strip(), 'lxml')
    
    # This will return any content found in tags called '<table>'
    table = soup.find_all('table') 
    

    这两个选项中我最喜欢的是 Selenium,但如果您对它更满意,请尝试第一个解决方案!

    【讨论】:

    • 添加了代码,请看一下。我想知道browser 来自哪个库? scrapy-splash 支持吗?
    • @SangHuynh Selenium
    • 太好了,非常感谢。
    • @SangHuynh 如果这对你有用,你能接受它作为答案吗?
    猜你喜欢
    • 1970-01-01
    • 2019-11-04
    • 2015-11-19
    • 2015-09-09
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    相关资源
    最近更新 更多