So, my problem is relatively simple. I have one spider crawling multiple sites, and I need it to return the data in the order I write it in my code. It’s posted below.
from scrapy.spider import BaseSpider
from scrapy.selector import HtmlXPathSelector
from mlbodds.items import MlboddsItem
class MLBoddsSpider(BaseSpider):
name = "sbrforum.com"
allowed_domains = ["sbrforum.com"]
start_urls = [
"http://www.sbrforum.com/mlb-baseball/odds-scores/20110328/",
"http://www.sbrforum.com/mlb-baseball/odds-scores/20110329/",
"http://www.sbrforum.com/mlb-baseball/odds-scores/20110330/"
]
def parse(self, response):
hxs = HtmlXPathSelector(response)
sites = hxs.select('//div[@id="col_3"]//div[@id="module3_1"]//div[@id="moduleData4952"]')
items = []
for site in sites:
item = MlboddsItem()
item['header'] = site.select('//div[@class="scoreboard-bar"]//h2//span[position()>1]//text()').extract()# | /*//table[position()<2]//tr//th[@colspan="2"]//text()').extract()
item['game1'] = site.select('/*//table[position()=1]//tr//td[@class="tbl-odds-c2"]//text() | /*//table[position()=1]//tr//td[@class="tbl-odds-c4"]//text() | /*//table[position()=1]//tr//td[@class="tbl-odds-c6"]//text()').extract()
items.append(item)
return items
The results are returned in a random order, for example it returns the 29th, then the 28th, then the 30th. I’ve tried changing the scheduler order from DFO to BFO, just in case that was the problem, but that didn’t change anything.
start_urlsdefines urls which are used instart_requestsmethod. Yourparsemethod is called with a response for each start urls when the page is downloaded. But you cannot control loading times – the first start url might come the last toparse.A solution — override
start_requestsmethod and add to generated requests ametawithprioritykey. Inparseextract thispriorityvalue and add it to theitem. In the pipeline do something based in this value. (I don’t know why and where you need these urls to be processed in this order).Or make it kind of synchronous — store these start urls somewhere. Put in
start_urlsthe first of them. Inparseprocess the first response and yield the item(s), then take next url from your storage and make a request for it with callback forparse.