bha*_*ram 12 python unit-testing scrapy web-scraping python-2.7
Scrapy合同问题
我开始研究scrapy框架.为了提取也实现了一些蜘蛛,但我无法为蜘蛛编写单元测试用例,因为scrapy提供的contract包文档没有正确的程序来编写测试用例.请帮帮我这件事.
adn*_*eam 11
测试蜘蛛的两个最基本的问题可能是:
Scrapy 提供了一种测试蜘蛛的方法:合约。
合同看起来有点神奇。它们存在于多行文档字符串中。合同“语法”是:@contract_name <arg>. 您可以创建自己的合同,这非常简洁。
要使用合同,请@在合同名称前加上 和。合约的名称由.name给定合约子类的属性指定。这些合约子类要么是内置的,要么是您创建的自定义子类。
最后,上述文档字符串必须存在于您的蜘蛛的回调中。这是parse回调中的一些基本合约的示例;默认回调。
def parse(self, response):
"""This function gathers the author and the quote text.
@url http://quotes.toscrape.com/
@returns items 1 8
@returns requests 0 0
@scrapes author quote_text
"""
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式运行此合约scrapy check;或者,列出您的合同scrapy check -l。
上述合约使用三个内置合约进行测试:
scrapy.contracts.default.UrlContractscrapy.contracts.default.ReturnsContractscrapy.contracts.default.ScrapesContract这UrlContract是强制性的,并不是真正的合同,因为它不用于验证。该@url合约用于设置蜘蛛在通过scrapy check. 在这种情况下,我们指定http://quotes.toscrape.com/. 但是我们可以指定http://127.0.0.1:8080/home-11-05-2019-1720.html哪个是quotes.toscrape.com我用scrapy view http://quotes.toscrape.com/命令保存的本地版本。
本ReturnsContract是用来检查你正在测试的回调的输出。如您所见,合约被调用了两次,参数不同。但是,您不能只在其中放置任何 ol' arg。在引擎盖下,有一个预期参数的字典:
objects = {
'request': Request,
'requests': Request,
'item': (BaseItem, dict),
'items': (BaseItem, dict),
}
Run Code Online (Sandbox Code Playgroud)
我们的合同规定了我们的蜘蛛@returns items 1 16。的1和16是下限和上限。上限是可选的;在引擎盖下,如果未指定,它将设置为无穷大。
try:
self.max_bound = int(self.args[2])
except IndexError:
self.max_bound = float('inf')
Run Code Online (Sandbox Code Playgroud)
但是,是的,这@returns可以帮助您了解您的蜘蛛是否返回了预期数量的项目或请求。
最后,@scrapes合约是最后一个内置的。它用于检查已抓取项目中是否存在字段。它只是遍历回调的输出字典并构建一个缺少属性的列表:
class ScrapesContract(Contract):
""" Contract to check presence of fields in scraped items
@scrapes page_name page_body
"""
name = 'scrapes'
def post_process(self, output):
for x in output:
if isinstance(x, (BaseItem, dict)):
missing = [arg for arg in self.args if arg not in x]
if missing:
raise ContractFail(
"Missing fields: %s" % ", ".join(missing))
Run Code Online (Sandbox Code Playgroud)
跑: scrapy check
如果一切顺利,你会看到:
...
----------------------------------------------------------------------
Ran 3 contracts in 0.140s
OK
Run Code Online (Sandbox Code Playgroud)
如果有东西爆炸,你会看到:
F..
======================================================================
FAIL: [example] parse (@returns post-hook)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/adnauseum/.virtualenvs/scrapy_testing-CfFR3tdG/lib/python3.7/site-packages/scrapy/contracts/__init__.py", line 151, in wrapper
self.post_process(output)
File "/Users/adnauseum/.virtualenvs/scrapy_testing-CfFR3tdG/lib/python3.7/site-packages/scrapy/contracts/default.py", line 90, in post_process
(occurrences, self.obj_name, expected))
scrapy.exceptions.ContractFail: Returned 10 items, expected 0
----------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
假设你想要一份@has_header X-CustomHeader合同。这将确保您的蜘蛛检查X-CustomHeader. Scrapy合同是有三个重写方法只是类:adjust_request_args,pre_process,和post_process。从那里,你需要提高ContractFail从pre_process或post_process每当期望没有实现。
...
----------------------------------------------------------------------
Ran 3 contracts in 0.140s
OK
Run Code Online (Sandbox Code Playgroud)
看起来合同可以帮助您了解两件事:
您的代码更改没有破坏事物
Site-Page-07-14-2019.html。您可以通过运行来保存这些页面scrapy view <url>。Scrapy 将在您的浏览器中打开此页面,但也会保存一个包含您需要的所有内容的 HMTL 文件。您正在抓取的页面没有改变(以影响您的方式)
尽管合同很有用,但您可能需要做更多的工作来确保您的蜘蛛。例如,您抓取的项目数量不能保证一直保持不变。在这种情况下,您可能会考虑抓取模拟服务器并针对收集的项目运行测试。似乎缺乏文档和最佳实践。
最后,有一个由 Scrapinghub 制作的项目,Spidermon,它对于在您的蜘蛛运行时监控它很有用:https ://spidermon.readthedocs.io/en/latest/getting-started.html
您可以根据模型定义验证抓取的项目并获取蜘蛛的统计信息(当前抓取的项目数量、不符合验证的项目数量等)。
| 归档时间: |
|
| 查看次数: |
2290 次 |
| 最近记录: |