У меня есть скребок, который запускает две страницы - одна из них является главной страницей, а другая - файлом .js, который содержит длинные и латинские координаты, которые мне нужно извлечь, потому что они понадобятся мне позже в процессе анализа. Сначала я хочу обработать файл .js, извлечь координаты, а затем проанализировать главную страницу и начать сканировать ее ссылки / анализировать ее элементы.
Для этого я использую параметр priority
в методе Request
и говорю, что хочу, чтобы моя страница .js была обработана первой. Это работает, но только в 70% случаев (должно быть из-за асинхронных запросов Scrapy). Остальные 30% времени я в конечном итоге пытаюсь проанализировать координаты long / lat в формате .js, но, пройдя главную страницу веб-сайта, их невозможно проанализировать.
По этой причине я попытался исправить это так:
в методе parse()
проверьте, какой это n-й URL, если он первый, а не .js, перезапустите паука. Однако, когда я перезагружаю паука в следующий раз, он сначала корректно передает файл .js, но после его обработки паук завершает работу и завершает работу сценария без ошибок, как если бы он был завершен.
Почему это происходит, в чем разница с обработкой страниц при перезапуске паука по сравнению с тем, когда я только запускаю его, и как я могу решить эту проблему?
Это код с примерами выходных данных в обоих сценариях, когда я пытался отладить то, что выполняется, и почему оно останавливается при перезапуске.
class QuotesSpider(Spider):
name = "bot"
url_id = 0
home_url = 'https://website.com'
longitude = None
latitude = None
def __init__(self, cat=None):
self.cat = cat.replace("-", " ")
def start_requests(self):
print ("Starting spider")
self.start_urls = [
self.home_url,
self.home_url+'js-file-with-long-lat.js'
]
for priority, url in enumerate(self.start_urls):
print ("Processing", url)
yield Request(url=url, priority=priority, callback=self.parse)
def parse(self, response):
print ("Inside parse")
if self.url_id == 0 and response.url == self.home_url:
self.alert("Loaded main page before long/lat page, restarting", False)
for _ in self.start_requests():
yield _
else:
print ("Everything is good, url id is", str(self.url_id))
self.url_id +=1
if self.longitude is None:
for _ in self.parse_long_lat(response):
yield _
else:
print ("Calling parse cats")
for cat in self.parse_cats(response):
yield cat
def parse_long_lat(self, response):
print ("called long lat")
try:
self.latitude = re.search('latitude:(\-?[0-9]{1,2}\.?[0-9]*)',
response.text).group(1)
self.longitude = re.search('longitude:(\-?[0-9]{1,3}\.?[0-9]*)',
response.text).group(1)
print ("Extracted coords")
yield None
except AttributeError as e:
self.alert("\nCan't extract lat/long coordinates, store availability will not be parsed. ", False)
yield None
def parse_cats(self, response):
pass
""" Parsing links code goes here """
Вывод, когда паук запускается правильно, сначала получает страницу .js, а второй начинает анализировать кошек:
Starting spider
https://website.com
https://website.com/js-file-with-long-lat.js
Inside parse
Everything is good, url id is 0
called long lat
Extracted coords
Inside parse
Everything is good, url id is 1
Calling parse cats
И сценарий продолжается и все хорошо разбирает.
Выводится, когда паук запускается неправильно, сначала получает главную страницу и перезапускает start_requests ():
Starting spider
https://website.com
https://website.com/js-file-with-long-lat.js
Inside parse
Loaded main page before long/lat page, restarting
Starting spider
https://website.com
https://website.com/js-file-with-long-lat.js
Inside parse
Everything is good, url id is 0
called long lat
Extracted coords
И сценарий останавливается без ошибок, как если бы он был завершен.
P.S. Если это имеет значение, я упомянул, что URL обработки в start_requests()
обрабатывается в обратном порядке, но я нахожу это естественным из-за последовательности циклов, и я ожидаю, что параметр priority
выполнит свою работу (как и большинство время, и оно должно делать это в соответствии с документами Scrapy).