在 Scrapy 中遍历 url params 模板
iterate through url params template in Scrapy
我有以下 url 开头:http://somedomain.mytestsite.com/?offset=0。我想通过递增 offset 参数来遍历此 url,比方说每次递增 100。每次我收到回复时,我都需要检查一些条件来决定我是否应该 运行 下一次迭代。例如:
class SomeSpider(BaseSpider):
name = 'somespider'
offset = 0
items = list()
def start_requests(self):
return [scrapy.Request("http://somedomain.mytestsite.com/?offset="+str(self.offset), callback=self.request_iterator)]
def request_iterator(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if data["matches"]:
self.items.extend(data["matches"])
self.offset += 100
return self.start_requests()
else:
#process collected data in items list
return self.do_something_with_items()
这行得通,但我不禁觉得这段代码有问题。也许我应该使用一些 scrapy 的 rules
?
以下内容可以改进:
1) 不要将项目保留为 spider 属性,输入更大会消耗大量内存,请改用 python 生成器。当您使用生成器时,您可以毫不费力地从一个蜘蛛回调中生成项目和请求。
2) start_requests
在 spider 启动时使用,似乎没有必要在你的代码中覆盖它们,如果你将你的方法重命名为解析(默认方法名称作为回调执行到 start_requests) 代码将更具可读性
# we should process at least one item otherwise data["matches"] will be empty.
start_urls = ["http://somedomain.mytestsite.com/?offset="+1]
def parse(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if data["matches"]:
for x in data["matches"]:
yield self.process_your_item(x)
self.offset += 100
yield self.next_request()
else:
#process collected data in items list
for x self.do_something_with_items():
yield x
def next_request(self):
return scrapy.Request("http://somedomain.mytestsite.com/?offset="+str(self.offset))
可能更好的回调版本是:
def parse(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if not data["matches"]:
self.logger.info("processing done")
return
for x in data["matches"]:
yield self.process_your_item(x)
self.offset += 100
yield self.next_request()
我有以下 url 开头:http://somedomain.mytestsite.com/?offset=0。我想通过递增 offset 参数来遍历此 url,比方说每次递增 100。每次我收到回复时,我都需要检查一些条件来决定我是否应该 运行 下一次迭代。例如:
class SomeSpider(BaseSpider):
name = 'somespider'
offset = 0
items = list()
def start_requests(self):
return [scrapy.Request("http://somedomain.mytestsite.com/?offset="+str(self.offset), callback=self.request_iterator)]
def request_iterator(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if data["matches"]:
self.items.extend(data["matches"])
self.offset += 100
return self.start_requests()
else:
#process collected data in items list
return self.do_something_with_items()
这行得通,但我不禁觉得这段代码有问题。也许我应该使用一些 scrapy 的 rules
?
以下内容可以改进:
1) 不要将项目保留为 spider 属性,输入更大会消耗大量内存,请改用 python 生成器。当您使用生成器时,您可以毫不费力地从一个蜘蛛回调中生成项目和请求。
2) start_requests
在 spider 启动时使用,似乎没有必要在你的代码中覆盖它们,如果你将你的方法重命名为解析(默认方法名称作为回调执行到 start_requests) 代码将更具可读性
# we should process at least one item otherwise data["matches"] will be empty.
start_urls = ["http://somedomain.mytestsite.com/?offset="+1]
def parse(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if data["matches"]:
for x in data["matches"]:
yield self.process_your_item(x)
self.offset += 100
yield self.next_request()
else:
#process collected data in items list
for x self.do_something_with_items():
yield x
def next_request(self):
return scrapy.Request("http://somedomain.mytestsite.com/?offset="+str(self.offset))
可能更好的回调版本是:
def parse(self, response):
body = response.body
#let's say we get json as response data
data = json.loads(body)
#check if page still have data to process
if not data["matches"]:
self.logger.info("processing done")
return
for x in data["matches"]:
yield self.process_your_item(x)
self.offset += 100
yield self.next_request()