python - 使用没有元数据的 start_url 将额外值传递给 Scrapy 蜘蛛

标签 python web-scraping scrapy

我已经从蜘蛛中抓取了项目,我正在编写另一个蜘蛛,它使用搜索引擎来填充一些缺失的数据。我想逐行更新第一个蜘蛛的项目。

但是,我不知道如何从 __init__ 方法传递当前行或 start_url。

我知道我可以将 meta 中的 request.url 传递给子请求,然后解析 meta 以提取公司名称,但看起来很尴尬。

class DuckDuckGoComSpider(scrapy.Spider):
    name = 'duckduckgo.com'

    def __init__(self, csv_file_path, *args, **kwargs):
        self.csv_file_path = csv_file_path
        super(DuckDuckGoComSpider, self).__init__(*args, **kwargs)
        with open(csv_file_path, newline='') as csvfile:
            for row in csv.DictReader(csvfile):
                self.start_urls.append(
                    f'https://duckduckgo.com/html/?q="website" {row["name"]} {row["location"]}')

    def parse(self, response):
        results = list(response.css('.result__url::attr(href)'))
        if len(results) > 0:
            for i in range(6):
                yield response.follow(results[i], callback=self.parse_item)
        else:
            self.logger.debug('No more products')

    def parse_item(self, response):
        il = DDGItemLoader(response=response)
        il.add_value('url', response.url)
        il.add_css('title', 'meta[property="og:title"]::attr(content)')
        il.add_css('description',
                   'meta[property="og:description"]::attr(content)')

        item = il.load_item()
        yield item

最佳答案

如 casper 所述,有几种方法可以将值传递给解析方法:

  1. start_requests() 中编写请求并在 meta 中传递所需数据
  2. 在类级别创建可用于引用所需数据的任何数据结构。数据可以在蜘蛛或自定义管道中更新

使用 meta 看起来像这样:

class DuckDuckGoComBatchSpider(scrapy.Spider):
    name = 'duckduckgo_batch.com'

    def __init__(self, csv_file_path, *args, **kwargs):
        self.csv_file_path = csv_file_path
        super(DuckDuckGoComBatchSpider, self).__init__(*args, **kwargs)

    def start_requests(self):
        pages = []
        with open(self.csv_file_path, newline='') as csvfile:
            reader = csv.DictReader(csvfile)
            self.fieldnames = reader.fieldnames
            for row in reader:
                url = f'https://duckduckgo.com/html/?q="website" {row["name"]} {row["location"]}'
                meta = {}
                for f in reader.fieldnames:
                    meta[f] = row[f]
                page = scrapy.Request(url, callback=self.parse, meta=meta)
                pages.append(page)

        return pages

    def parse(self, response):
        results = list(response.css('.result__url::attr(href)'))
        if len(results) > 0:
            yield response.follow(results[0], callback=self.parse_item,
                                  meta=response.meta)
        else:
            self.logger.debug('No more products')

    def parse_item(self, response):
        il = DDGItemLoader(response=response)
        il.add_value('website', response.url)
        il.add_css('website_title', 'meta[property="og:title"]::attr(content)')
        il.add_css('website_description',
                   'meta[property="og:description"]::attr(content)')
        il.add_value('name', response.meta["name"])

        item = il.load_item()
        for key in response.meta:
            if key in self.fieldnames:
                item[key] = response.meta[key]
        yield item

关于python - 使用没有元数据的 start_url 将额外值传递给 Scrapy 蜘蛛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49617989/

相关文章:

python - 根据相机的方向在 HUD 上移动 3d 点

python - 在事后模式下运行 django-pdb 来执行测试命令

java - 网络抓取工具不创建 CSV 文件

python - 通过 Python 脚本抓取动态网站 : how to get the values?

python - scrapy中通过回调函数传递元元素

python - Scrapy 产生一个请求,在回调中解析,但使用原始函数中的信息

python,返回位置和文件大小

javascript - Python、Flask - 如何使用 DHTML uploader 加载文件

python - 使用 BeautifulSoup 提取标签之间的文本

python - 使用 scrapy 遍历嵌套标签中文本中的列表和 strip 标签