[英]How to scrape element form scraped url? Scrapy
好的,假设我有一个列出工作机会的网站,并且有多个页面(动态的,这就是我使用 selenium 的原因)。 我想做的事:
class JobScraper(scrapy.Spider):
name = "jobscraper"
allowed_domains = ['pracuj.pl']
total = 10
start_urls = [
'https://www.pracuj.pl/praca/it%20-%20rozw%c3%b3j%20oprogramowania;cc,5016/%c5%82%c3%b3dzkie;r,5?rd=10&pn={}'.format(i)
for i in range(1, total)
]
custom_settings = {
'LOG_LEVEL': 'INFO',
}
def __init__(self):
self.options = webdriver.ChromeOptions()
self.options.headless = True
self.driver = webdriver.Chrome(r'C:\Users\kacpe\OneDrive\Pulpit\Python\Projekty\chromedriver.exe',
options=self.options)
def parse(self, response):
self.driver.get(response.url)
res = response.replace(body=self.driver.page_source)
offers = res.xpath('//li[contains(@class, "results__list-container")]')
for offer in offers:
link = offer.xpath('.//a[@class="offer-details__title-link"]/@href').extract()
yield Request(link, callback=self.parse_page)
def parse_page(self, response):
title = response.xpath('//h1[@data-scroll-id="job-title"]/text()').extract()
yield {
'job_title': title
}
而且它不起作用,发生了一个错误:
TypeError: 请求 url 必须是 str 或 unicode,得到列表
您在这一行中调用extract
:
link = offer.xpath('.//a[@class="offer-details__title-link"]/@href').extract()
Extract 返回一个元素列表,这就是您尝试将link
传递给Request
时收到错误的原因。
根据您想要执行的操作,您可以for link in links
执行操作并Request
每个结果,或者使用find_elements_by_xpath
xpath
您不需要 selenium 来抓取所需的内容。 事实证明,您希望从该站点获取的项目位于某个脚本标记中。 一旦您使用正则表达式挖出该部分并使用 json 库处理它,您应该非常轻松地访问它们。 以下是我的意思:
import json
import scrapy
class JobScraper(scrapy.Spider):
name = "jobscraper"
total = 10
start_urls = [
'https://www.pracuj.pl/praca/it%20-%20rozw%c3%b3j%20oprogramowania;cc,5016/%c5%82%c3%b3dzkie;r,5?rd=10&pn={}'.format(i)
for i in range(1, total)
]
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36'
}
def start_requests(self):
for start_url in self.start_urls:
yield scrapy.Request(start_url,callback=self.parse,headers=self.headers)
def parse(self, response):
items = response.css("script:contains('window.__INITIAL_STATE__')::text").re_first(r"window\.__INITIAL_STATE__ =(.*);")
for item in json.loads(items)['offers']:
yield {
"title":item['jobTitle'],
"employer":item['employer'],
"country":item['countryName'],
"details_page":item['companyProfileUrl']
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.