我是Python和Scrapy的新手。我之前没有使用过回调函数。但是,我现在为下面的代码做。将执行第一个请求,并将其响应发送到定义为第二个参数的回调函数:
def parse_page1(self, response):
item = MyItem()
item['main_url'] = response.url
request = Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
request.meta['item'] = item
return request
def parse_page2(self, response):
item = response.meta['item']
item['other_url'] = response.url
return item
我无法理解以下事项:
item
如何填充?request.meta
行是否在response.meta
的{{1}}行之前执行?parse_page2
返回item
的位置在哪里?parse_page2
中return request
语句的需求是什么?我认为提取的物品需要从这里返回。答案 0 :(得分:16)
阅读docs:
对于蜘蛛,刮擦周期会经历这样的事情:
首先生成初始请求以抓取第一个URL,然后指定要使用响应调用的回调函数 从这些请求下载。
首先要求执行的请求是通过调用
start_requests()
方法(默认情况下)生成Request
start_urls
和parse
方法中指定的网址作为回调 请求的功能。在回调函数中,您解析响应(网页)并返回
Item
个对象,Request
个对象或两者的可迭代对象。 那些请求也将包含一个回调(可能是相同的)和将 然后由Scrapy下载,然后由他们处理他们的响应 指定的回调。在回调函数中,您通常使用选择器来解析页面内容(但您也可以使用BeautifulSoup,lxml或其他 您喜欢的机制)并使用已解析的数据生成项目。
- 醇>
最后,从蜘蛛返回的项目通常会持久保存到数据库(在某些项目管道中)或写入文件 使用 Feed导出。
数目:
在
'item'
request.meta
行之前,response.meta
行执行parse_page2
行的效果如何?
蜘蛛由Scrapy引擎管理。它首先从start_urls
中指定的URL发出请求,然后将其传递给下载程序。下载完成后,将调用请求中指定的回调。如果回调返回另一个请求,则重复相同的操作。如果回调返回Item
,则该项目将传递给管道以保存已删除的数据。
parse_page2
返回的项目在哪里?
return request
中parse_page1
声明的需要是什么?我认为提取的物品需要从这里返回?
正如文档中所述,每个回调(parse_page1
和parse_page2
)都可以返回Request
或Item
(或其中的可迭代)。 parse_page1
会返回Request
而不是Item
,因为需要从其他网址中删除其他信息。第二个回调parse_page2
返回一个项目,因为所有信息都已被删除并准备好传递给管道。
答案 1 :(得分:1)
parse_page1
返回它并避免额外的http请求电话答案 2 :(得分:1)
,eLRuLL的答案很棒。
我想添加项目转换的一部分。首先,我们将清楚回调函数只有在此请求的响应被重载之后才会起作用。
在scrapy.doc给出的代码中,它不会声明page1和的url和请求。我们将page1的网址设置为" http://www.example.com.html"。
[parse_page1]是
的回调scrapy.Request("http://www.example.com/some_page.html",callback=parse_page2)
[parse_page2]是
的回调item['main_url'] = response.url # send "http://www.example.com.html" to item
request = scrapy.Request("http://www.example.com/some_page.html",
callback=self.parse_page2)
request.meta['item'] = item # store item in request.meta
当下载page1的响应时,调用parse_page1来生成page2的请求:
item = response.meta['item']
#response.meta is equal to request.meta,so here item['main_url']
#="http://www.example.com.html".
item['other_url'] = response.url # response.url ="http://www.example.com/some_page.html"
return item #finally,we get the item recording urls of page1 and page2.
下载page2的响应后,调用parse_page2来重新启动项目:
@Html.TextBox(property.Name, "2017/08/24T09:31:00", new {@type="datetime-local", @step="1", @class="form-control"});
@Html.ValidationMessage(property.Name, "", new { @class = "text-danger" })