Я только что провел быструю проверку вашего скребка, и мне кажется, что он на самом деле работает так, как должен.
РЕДАКТИРОВАТЬ: В попытке сделать мое объяснение более четким;Вы не можете очистить 301 или 302 перенаправления, потому что они - только это;перенаправляет. Если вы запрашиваете URL-адрес, который перенаправляется, Scrapy автоматически обрабатывает его и удаляет данные со страницы, на которую вы перенаправлены. Это конечный пункт назначения из перенаправления, который даст вам ответ 200.
Если вы будете следовать логике, представленной ниже, вы увидите, что Scrapy запрашивает URL http://www.indeed.com/rc/clk?jk=69995bf12d9f2f9a&fccid=b87e01ade6c824ee&vjs=3,, но перенаправляется на https://www.indeed.com/viewjob?jk=69995bf12d9f2f9a&from=serp&vjs=3. Это последняя страница, которую вы сможете почистить. (Вы можете попробовать это самостоятельно, щелкнув начальный URL-адрес и сравнив его с последним URL-адресом, на котором вы в конечном итоге)
Просто повторюсь, вы не сможете очиститьчто-нибудь из 301 и 302 перенаправлений (там нечего очищать), только последняя страница, которая получает ответ 200.
Я приложил предложенную версию вашего скребка, котораясохраняет как запрошенный URL, так и очищенный URL. Все выглядит хорошо для меня, ваш скребок работает так, как положено. (Тем не менее, обратите внимание, что действительно.com будет обслуживать вас только до 19 страниц результатов поиска, что ограничивает вас 190 записками)
Надеюсь, теперь это имеет смысл.
Вот один пример из вывода, начиная с исходного запроса:
2019-09-30 10:37:06 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (301) to <GET https://www.indeed.com/rc/clk?jk=69995bf12d9f2f9a&fccid=b87e01ade6c824ee&vjs=3> from <GET http://www.indeed.com/rc/clk?jk=69995bf12d9f2f9a&fccid=b87e01ade6c824ee&vjs=3>
Это перенаправляется с 301 перенаправлением на следующую ссылку:
2019-09-30 10:37:06 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.indeed.com/viewjob?jk=69995bf12d9f2f9a&from=serp&vjs=3> from <GET https://www.indeed.com/rc/clk?jk=69995bf12d9f2f9a&fccid=b87e01ade6c824ee&vjs=3>
Который снова перенаправляется с перенаправлением 302 на следующую ссылку:
2019-09-30 10:37:07 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.indeed.com/viewjob?jk=69995bf12d9f2f9a&from=serp&vjs=3> (referer: None)
И, наконец, мы можем очистить данные:
2019-09-30 10:37:07 [scrapy.core.scraper] DEBUG: Scraped from <200 https://www.indeed.com/viewjob?jk=69995bf12d9f2f9a&from=serp&vjs=3>
{'title': 'General Manager', 'posting_url': 'https://indeed.com/rc/clk?jk=69995bf12d9f2f9a&fccid=b87e01ade6c824ee&vjs=3', 'job_name': 'General Manager', 'job_location': 'Plano, TX 75024', 'job_description_1': [], 'posted_on_date': ' - 30+ days ago', 'job_description_2': None}
Таким образом, данные извлекаются изпоследняя страница, получившая ответ 200. Обратите внимание, что в извлеченном элементе posting_url
- это страница, переданная с атрибутом meta
, а не фактический очищенный URL. Это может быть то, что вы хотите, но если вы хотите сохранить фактический URL, который был очищен, то вы должны использовать posting_url = response.url
вместо этого. РЕДАКТИРОВАТЬ: см. Предлагаемое обновление ниже
Рекомендуемое обновление кода:
import scrapy
class JobsSpider(scrapy.Spider):
name = "jobs"
allowed_domains = ["indeed.com"]
start_urls = ["https://www.indeed.com/jobs?q=%22owner+operator%22&l=dallas"]
def parse(self, response):
jobs = response.xpath('//div[@class="title"]')
for job in jobs:
title = job.xpath('a//@title').extract_first()
posting_link = job.xpath('a//@href').extract_first()
referer_url = "https://indeed.com" + posting_link
yield scrapy.Request(url=referer_url,
callback=self.parse_page,
meta={'title': title,
'referer_url': referer_url,
}
)
relative_next_url = response.xpath('//link[@rel="next"]/@href').extract_first()
if relative_next_url:
absolute_next_url = "https://indeed.com" + relative_next_url
yield scrapy.Request(absolute_next_url, callback=self.parse)
else:
self.logger.info('No more pages found.')
def parse_page(self, response):
referer_url = response.meta.get('referer_url')
title = response.meta.get('title')
job_location = response.meta.get('job_location')
posting_url = response.url
job_name= response.xpath('//*[@class="icl-u-xs-mb--xs icl-u-xs-mt--none jobsearch-JobInfoHeader-title"]/text()').extract_first()
job_description_1=response.xpath('//div[@class="jobsearch-jobDescriptionText"]/ul').extract()
posted_on_date= response.xpath('//div[@class="jobsearch-JobMetadataFooter"]/text()').extract_first()
job_location=response.xpath('//*[@class="jobsearch-InlineCompanyRating icl-u-xs-mt--xs jobsearch-DesktopStickyContainer-companyrating"]/div[3]/text()').extract_first()
job_description_2=response.xpath('//div[@class="jobsearch-JobComponent-description icl-u-xs-mt--md "]/text()').extract_first()
yield {'title': title,
'posting_url': posting_url,
'referer_url': referer_url,
'job_name': job_name,
'job_location': job_location,
'job_description_1': job_description_1,
'posted_on_date': posted_on_date,
'job_description_2': job_description_2,
'job_location': job_location
}