渲染使用框架集的页面

Render page that use frameset

我正在使用 scrapy + splash 来抓取我大学的网站。有些页面是古老的,并且使用了我不熟悉的技术。我注意到一些网站没有完全呈现。所有不完整的页面都使用 <frameset> 而不是传统的 <body>。通过 splash gui,页面似乎完全呈现(我可以看到快照)但是 html 不包含框架 src 中的内容。这是一些说明我的问题的代码:

import scrapy
from scrapy_splash import SplashRequest

class Frameset(scrapy.Spider):

    name = 'frameset'

    def start_requests(self):
        yield SplashRequest(
            'http://www.cs.odu.edu/~cs411/Summer03/AquaTrac/',
            endpoint = 'render.json',
            args = { 
                'iframes': 1,
                'html': 1,
                'timeout': 10, 
            }   
        )   

        ##yield scrapy.Request(
        ##    'http://www.cs.odu.edu/~cs411/Summer03/AquaTrac/',
        ##    meta = {
        ##        'splash': {
        ##            'endpoint': 'render.json',
        ##            'args': {
        ##                'iframes': 1,
        ##                'html': 1,
        ##                'timeout': 5,
        ##            }
        ##        }
        ##    }
        ##) 

    def parse(self, response):
        print(response.xpath('//html').extract())

它呈现正确,但这就是返回的所有 html:

<html><head><title>« AquaTrac »</title>
</head><frameset rows="120,2,25,2,*,2,25" framespacing="0" frameborder="NO" border="0">
<frame name="banner" scrolling="no" noresize="" src="banner.htm">
<frame name="space" scrolling="no" noresize="" src="about:blank">
<frame name="links" scrolling="no" noresize="" src="links.htm">
<frame name="space" scrolling="no" noresize="" src="about:blank">
<frame name="main" scrolling="auto" noresize="" src="main.htm">
<frame name="space" scrolling="no" noresize="" src="about:blank">
<frame name="info" scrolling="no" noresize="" src="info.htm">
</frameset>
</html>

我想在 1 个请求中获取所有 html,而不必尽可能向每个帧 src 发出多个请求。如果您在 chrome 或 firefox 中使用开发者模式,您将看到整个 html 包括来自框架 src 的内容。从生成的快照来看,splash 应该也有整个 html。有没有办法使用 splash 和 scrapy 在单个请求中获取所有 html?

您需要使用 render.json 端点和 iframes 选项:

def start_requests(self):
       yield SplashRequest(self.root_url, self.parse_detail,
            endpoint='render.json',
            args={
                'iframes': 1,
                'html' : 1,
                'timeout': 90
            }
        ) 
def parse(self, response):

    for frame in response["data"]["childFrames"]:
        frame_html = frame["html"]