【问题标题】:Scrapy and submitting a javascript formScrapy 并提交一个 javascript 表单
【发布时间】:2014-03-04 13:57:50
【问题描述】:

我正在学习 scrapy,但在尝试提交由 javascript 控制的表单时遇到了障碍。

我已经尝试过在 Stack Overflow 上发现了很多东西,包括 Selenium,但没有运气(出于多种原因)。

我需要抓取的页面是... http://agmarknet.nic.in/

...然后进行商品搜索。当我检查元素时,它似乎有一个表格“m”,一个归档的“cmm”需要商品价值。

<form name="m" method="post">
(...)
<input type="text" name="cmm" onchange="return validateName(document.m.cmm.value);" size="13">
(...)
<input type="button" value="Go" name="Go3" style="color: #000080; font-size: 8pt; font-family: Arial; font-weight: bold" onclick="search1();"></td>

任何建议都欣然接受!

更新: 我已经用硒尝试过这个,但它没有找到或填充该字段。我也不介意在不弹出 Firefox 窗口的情况下执行此操作...

    CrawlSpider.__init__(self)
    self.verificationErrors = []

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys

    driver = webdriver.Firefox()
    driver.get("http://agmarknet.nic.in/")
    time.sleep(4)
    elem = driver.find_element_by_name("cmm")
    elem.send_keys("banana")
    time.sleep(5)
    elem.send_keys(Keys.RETURN)
    driver.close()        

更新:

我还尝试了以下各种迭代,但没有运气。当我从网页提交搜索时,fiddler2 告诉我它正在发布字符串“cmm=banana&mkt=&search="...但是当我使用下面的代码时,fiddler 告诉我没有发布任何内容...

class Agmarknet(Spider):
    name = "agmarknet"
    start_urls = ["http://agmarknet.nic.in/SearchCmmMkt.asp"]


    def parse(self, response):
        return [FormRequest.from_response(
                    response,
                   #formname = "cmm1", 
                    formdata={
                    'method':'post',
                    'cmm': 'banana', 
                    'mkt': '', 
                    'search':''},
                    callback=self.after_search)]

    def after_search(self):
        print response.body

上面的输出:

{'download_timeout': 180, 'download_latency': 13.44700002670288, 'proxy': 'http://127.0.0.1:8888', 'download_slot': 'agmarknet.nic.in'}
Spider error processing <GET http://agmarknet.nic.in/SearchCmmMkt.asp>
Traceback (most recent call last):
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\twisted\internet\base.py", line 1201, in mainLoop
    self.runUntilCurrent()
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\twisted\internet\base.py", line 824, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\twisted\internet\defer.py", line 382, in callback
    self._startRunCallbacks(result)
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\twisted\internet\defer.py", line 490, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\twisted\internet\defer.py", line 577, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "Z:\WindowsDocuments\eclipseworkspaces\BioCom\manoliagro-agmarknetscraper\src\bin\agmarknetscraper\spiders\agmarknet.py", line 34, in parse
    callback=self.after_search)]
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\scrapy-0.22.0-py2.7.egg\scrapy\http\request\form.py", line 36, in from_response
    form = _get_form(response, formname, formnumber, formxpath)
  File "Z:\WinPython-32bit-2.7.6.2\python-2.7.6\lib\site-packages\scrapy-0.22.0-py2.7.egg\scrapy\http\request\form.py", line 59, in _get_form
    raise ValueError("No <form> element found in %s" % response)
exceptions.ValueError: No <form> element found in <200 http://agmarknet.nic.in/SearchCmmMkt.asp>
SpiderRun done

【问题讨论】:

    标签: javascript python forms scrapy


    【解决方案1】:

    显然该页面由两个框架组成,对源代码的简短浏览会发现它们的名称“内容”和“主要”。因此,您上面的脚本几乎可以完成这项工作,只是缺少一条指向名为“main”的正确框架的行,其中包含 driver.switch_to_frame('main')。此外,表单对 ENTER 键没有反应,我们确实必须选择按钮并按下它:-)。

    此代码正在运行:

    import time
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    
    driver = webdriver.Firefox()
    driver.get("http://agmarknet.nic.in/")
    time.sleep(4)
    
    driver.switch_to_frame('main')
    textinput = driver.find_element_by_name('cmm')
    textinput.send_keys("banana")
    time.sleep(1)
    
    button = driver.find_element_by_name("Go3")
    button.click()
    driver.close()
    

    【讨论】:

    • 巴里奥斯。谢谢!杰出的!如果可以的话,我有一个后续问题......是否可以在没有实际弹出浏览器的情况下从搜索后页面抓取数据(在后台静音)
    • TNX 的恭维,并不难弄清楚:-)。您确实可以使用所谓的“无头”浏览器,例如带有 selenium 的 PhantomJS,它没有显示。我不知道这个浏览器的效果如何。如果您使用的是 linux 机器,您还可以使用 xvfbwrapper 将 Firefox 放在 X-window-system 中的虚拟帧缓冲区上
    • 嘿...所以我遇到了同样问题的另一个错误。我不确定是否适合在这里发布,所以我开始了一个新线程...stackoverflow.com/questions/22203080/…
    【解决方案2】:

    不管有没有 javascript,最后,调用都会总是被翻译成一些 http 调用,使用 firebug 来追踪调用类型(get/post),它被翻译的字段和值并将它们添加到您的scrapy请求中。

    【讨论】:

      【解决方案3】:

      Selenium IDE 会让您的生活更轻松,尤其是使用 javascript。它是一个 Firefox 插件,能够记录您在 Firefox 中单击和输入的内容,然后向您显示您需要放入 python 脚本中的某些元素的代码。对我来说非常有用,不仅仅是表格。 :-)

      试试看!

      【讨论】:

      • 感谢您的意见。我会研究一下IDE。我确实使用了 Fiddler2,我认为它是一个类似于 name=cmm&mkt=&search= 的发布请求,但我无法通过 scrapy 请求获得发布请求。你能指导我一些代码 sn-ps 吗?
      • 所以,我用 Firefox 尝试了 selenium IDE,它实际上没有记录任何内容。它只显示了一个 OpenAndWait,仅此而已,尽管我完成了搜索并获得了结果。
      猜你喜欢
      • 2012-05-27
      • 2018-02-09
      • 2014-02-06
      • 2016-03-21
      • 2012-04-09
      • 2012-10-22
      • 2017-07-24
      • 1970-01-01
      • 2014-10-14
      相关资源
      最近更新 更多