渲染使用框架集的页面

问题描述 投票:0回答:1

我正在使用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包括来自frame src的内容。根据快照启动生成,splash也应该包含整个html。有没有办法使用splash和scrapy在一个请求中获取所有html?

python-3.x web-scraping scrapy frameset scrapy-splash
1个回答
0
投票

您需要使用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"]
© www.soinside.com 2019 - 2024. All rights reserved.