【问题标题】:How to pass a variable to lua script being executed inside scrapy from the command prompt?如何从命令提示符将变量传递给在scrapy内部执行的lua脚本?
【发布时间】:2020-10-12 19:31:04
【问题描述】:

我正在尝试在scrapy中传递一个变量作为用户定义的参数,该参数将用于lua脚本的for循环,我的代码如下:

import scrapy
from scrapy_splash import SplashRequest
from scrapy.selector import Selector


class ProductsSpider(scrapy.Spider):
    name = 'allproducts'

    script = '''
        function main(splash, args)
           assert(splash:go(args.url))
           assert(splash:wait(0.5))
           result = {}
           local upto = tonumber(splash.number)
           for i=1,upto,1
           do
             #something
           end
           return output
        
        end
    '''

    def start_requests(self):
        url='https://medicalsupplies.co.uk'
        yield SplashRequest(url=url, callback=self.parse, endpoint='render.html', args={'wait':0.5})
        yield SplashRequest(url=url, callback=self.parse_other_pages, endpoint='execute',
            args={'wait':0.5, 'lua_source':self.script, 'number':int(self.number)}, dont_filter=True)

    def parse(self, response):
        for tr in response.xpath("//table[@id='date']/tbody/tr"):
            yield{
                    'output' : #something
            }

    def parse_other_pages(self,response):
        for page in response.data:
            sel=Selector(text=page)
            for tr in sel.xpath("//table[@id='date']/tbody/tr"):
                yield{
                     'output' : #something
                   }

所以,我面临的问题是,当我使用整数(即for i=1,5,1)运行 lua 脚本的 for 循环时,脚本工作得很好,但是当我尝试从命令提示符使用scrapy crawl allproducts -a number=5 -o test.json 在脚本内的 for 循环中使用 for i=1,{self.number},1 时,我的代码抛出了一个错误,我什至无法在这个字符串上使用 f 字符串,有没有办法解决如何将变量传递给文本字符串(这里称为脚本)而不破坏代码?我知道我没有使用正确的语法,但我没有找到任何相同的资源,感谢任何建议。

来自scraper的实际警告如下:

WARNING: Bad request to Splash: {'error': 400, 'type': 'ScriptError', 'description': 'Error happened while executing Lua script', 'info': {'source': '[string "..."]', 'line_number': 7, 'error': "attempt to index global 'self' (a nil value)", 'type': 'LUA_ERROR', 'message': 'Lua error: [string "..."]:7: attempt to index global \'self\' (a nil value)'}}

编辑 1:根据@Alexander 的建议,修改了 lua 脚本并将变量作为整数参数传递给 SplashRequest,还使用 ​​local (local upto = tonumber(splash.number)) 实例化了 lua 脚本中的变量

现在的警告如下:

 WARNING: Bad request to Splash: {'error': 400, 'type': 'ScriptError', 'description': 'Error happened while executing Lua script', 'info': {'source': '[string "..."]', 'line_number': 9, 'error': "'for' limit must be a number", 'type': 'LUA_ERROR', 'message WARNING: Bad request to Splash: {'error': 400, 'type': 'ScriptError', 'description': 'Error happened while executing Lua script', 'info': {'source': '[string "..."]', 'line_number': 9, 'error': "'for' limit must be a number", 'type': 'LUA_ERROR', 'message': 'Lua error: [string "..."]:9: \'for\' limit must be a number'}}

【问题讨论】:

    标签: python-3.x lua scrapy scrapy-splash


    【解决方案1】:

    function main(splash, args) 没有 self 参数。然而第 5 行引用了它:for i=1,{self.number},1。并且该函数不是使用: 声明的方法(函数类型的Lua 表的字段),其中self 是该表。

    你是说splash吗?

    我认为,您应该在 Python 代码 (start_requests) 中将 'number':self.number 添加到 args,然后在 Lua 脚本中将其称为 tonumber(args.number)

    【讨论】:

    • 我的意思是 ProductsSpider 类的自我,因为脚本在同一个类中,我相信脚本会识别自我,不是吗?
    • @Freak,不,我不这么认为。将 Python 对象映射到 Lua 表是很困难的,如果不是不可能的话。查看更新的答案。
    • script = ''' function main(splash, args) assert(splash:go(args.url)) assert(splash:wait(0.5)) result = {} upto = splash.number for i=1,upto,1 do #something end return output end ''' 我像你提到的那样尝试过,但似乎仍然没有帮助,我得到了同样的警告
    • @Freak,是的,我的意思是这样的。
    • 运气不好。似乎splash.number 为零。你也可以试试args.numbersplash.args.number。如果做不到这一点,您可以将数字连接到您的 Python script 变量中。
    猜你喜欢
    • 2019-08-24
    • 1970-01-01
    • 2013-12-07
    • 2018-01-11
    • 2019-07-28
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多