标签: scrapy-pipeline

Scrapy:如何在蜘蛛中使用物品以及如何将物品发送到管道?

我是新手scrapy,我的任务很简单:

对于给定的电子商务网站:

  • 抓取所有网站页面

  • 寻找产品页面

  • 如果URL指向产品页面

  • 创建一个项目

  • 处理项目以将其存储在数据库中

我创建了蜘蛛,但产品只是打印在一个简单的文件中.

我的问题是项目结构:如何在蜘蛛中使用物品以及如何将物品发送到管道?

我找不到使用项目和管道的项目的简单示例.

python scrapy scrapy-spider scrapy-pipeline

14
推荐指数
1
解决办法
1万
查看次数

在Scrapy中关闭来自管道和中间件的数据库连接

我有一个使用自定义的中间件和自定义管道检查和存储条目在一个Postgres数据库一个Scrapy项目.中间件看起来有点像这样:

class ExistingLinkCheckMiddleware(object):

    def __init__(self):

        ... open connection to database

    def process_request(self, request, spider):

        ... before each request check in the DB
        that the page hasn't been scraped before

管道看起来很相似:

class MachinelearningPipeline(object):

    def __init__(self):

        ... open connection to database

    def process_item(self, item, spider):

        ... save the item to the database

它运行正常,但是当蜘蛛完成时我无法找到干净地关闭这些数据库连接的方法,这让我感到烦恼.

有谁知道这是怎么做到的吗?

python scrapy web-scraping scrapy-pipeline

5
推荐指数
1
解决办法
2050
查看次数

保存已删除的项目和文件时,Scrapy会在输出csv文件中插入空行

我有Scrapy(版本1.0.3)蜘蛛,其中我从网页中提取了一些数据,我也下载了文件,像这样(简化):

def extract_data(self, response):
    title = response.xpath('//html/head/title/text()').extract()[0].strip()
    my_item = MyItem()
    my_item['title'] = title    

    file_url = response.xpath('...get url of file...')
    file_urls = [file_url]  # here there can be more urls, so I'm storing like a list
    fi = FileItem()
    fi['file_urls'] = file_urls 
    yield my_item
    yield fi
Run Code Online (Sandbox Code Playgroud)

在pipelines.py中我只是重写FilePipeline来更改文件的名称:

from scrapy.pipelines.files import FilesPipeline

class CustomFilesPipeline(FilesPipeline):
    def file_path(self, request, response=None, info=None):
        filename = format_filename(request.url)
        return filename
Run Code Online (Sandbox Code Playgroud)

在items.py我有:

class MyItem(scrapy.Item):
    title = scrapy.Field()

class FileItem(scrapy.Item):
    file_urls = scrapy.Field()
    files = scrapy.Field()
Run Code Online (Sandbox Code Playgroud)

在settings.py我有:

ITEM_PIPELINES = { …
Run Code Online (Sandbox Code Playgroud)

python scrapy scrapy-spider scrapy-pipeline

5
推荐指数
1
解决办法
928
查看次数

scrapy-处理多种类型的项目-多个和相关的Django模型,并将它们保存到管道中的数据库中

我有以下Django模型。我不确定使用scrapy管道在Spider中扫描到Django中的数据库时,保存这些相互关联的对象的最佳方法是什么。似乎刮擦的管道仅用于处理一种“种类”的物料

models.py

class Parent(models.Model):
    field1 = CharField()


class ParentX(models.Model):
    field2 = CharField()
    parent = models.OneToOneField(Parent, related_name = 'extra_properties')


class Child(models.Model):
    field3 = CharField()
    parent = models.ForeignKey(Parent, related_name='childs')
Run Code Online (Sandbox Code Playgroud)

items.py

# uses DjangoItem https://github.com/scrapy-plugins/scrapy-djangoitem

class ParentItem(DjangoItem):
    django_model = Parent

class ParentXItem(DjangoItem):
    django_model = ParentX

class ChildItem(DjangoItem):
    django_model = Child
Run Code Online (Sandbox Code Playgroud)

蜘蛛

class MySpider(scrapy.Spider):
    name = "myspider"
    allowed_domains = ["abc.com"]
    start_urls = [
        "http://www.example.com",       # this page has ids of several Parent objects whose full details are in their individual pages

    ]

    def parse(self, …
Run Code Online (Sandbox Code Playgroud)

python django scrapy scrapy-spider scrapy-pipeline

5
推荐指数
1
解决办法
908
查看次数

Twisted (Scrapy) 和 Postgres

我使用 Scrapy(又名 Twisted)和 Postgres 作为数据库。

在我之后,虽然我的连接似乎填满了,然后我的脚本被卡住了。我用这个查询检查了这个SELECT * FROM pg_stat_activity;并读到它是因为 Postgres 没有连接池造成的。

我读过txpostgresPGBouncer,遗憾的是 Bouncer 不是一个选项,我还能做些什么来避免这个问题?

到目前为止,我使用以下管道

import psycopg2
from twisted.enterprise import adbapi
import logging
from datetime import datetime
import scrapy
from scrapy.exceptions import DropItem


class PostgreSQLPipeline(object):
    """ PostgreSQL pipeline class """

    def __init__(self, dbpool):
        self.logger = logging.getLogger(__name__)
        self.dbpool = dbpool

    @classmethod
    def from_settings(cls, settings):
        dbargs = dict(
                host=settings['POSTGRESQL_HOST'],
                database=settings['POSTGRESQL_DATABASE'],
                user=settings['POSTGRESQL_USER'],
                password=settings['POSTGRESQL_PASSWORD'],
        )
        dbpool = adbapi.ConnectionPool('psycopg2', **dbargs)
        return cls(dbpool)

    def process_item(self, item, spider):
        d …
Run Code Online (Sandbox Code Playgroud)

postgresql psycopg2 twisted scrapy-pipeline

5
推荐指数
0
解决办法
1250
查看次数

Django与Scrapy的关系如何保存物品?

我只需要了解如何检测scrapy是否已保存以及蜘蛛中的项目?我正在从网站上获取项目,之后我正在获取该项目的评论.所以首先我必须保存项目,之后我会保存评论.但是当我在编写代码之后编写代码时,它会给我这个错误.

save() prohibited to prevent data loss due to unsaved related object ''.

这是我的代码

def parseProductComments(self, response):

        name = response.css('h1.product-name::text').extract_first()
        price = response.css('span[id=offering-price] > span::text').extract_first()
        node = response.xpath("//script[contains(text(),'var utagData = ')]/text()")
        data = node.re('= (\{.+\})')[0]  #data = xpath.re(" = (\{.+\})")
        data = json.loads(data)

        barcode = data['product_barcode']

        objectImages = []
        for imageThumDiv in response.css('div[id=productThumbnailsCarousel]'):
            images = imageThumDiv.xpath('img/@data-src').extract()
            for image in images:
                imageQuality = image.replace('/80/', '/500/')
                objectImages.append(imageQuality)
        company = Company.objects.get(pk=3)
        comments = []
        item = ProductItem(name=name, price=price, barcode=barcode, file_urls=objectImages, product_url=response.url,product_company=company, comments = …
Run Code Online (Sandbox Code Playgroud)

python django scrapy scrapy-spider scrapy-pipeline

5
推荐指数
1
解决办法
533
查看次数

Scrapy管道分隔文件夹/文件-抽象

我目前正在完成一个Scrapy项目,但是我的pipelines.py文件很长。

我注意到在我settings.py的管道中显示如下(修剪掉):

ITEM_PIPELINES = {
     'proj.pipelines.MutatorPipeline': 200,
     'proj.pipelines.CalculatorPipeline': 300,
     'proj.pipelines.SaveToFilePipeline': 500,
}
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法来纠正此问题。

1.)我创建了一个新的文件/文件夹,并尝试以相同的方式从管道中引用它。

Folder myPipelines/Test.py的类名为,TestPipeline然后在管道设置中引用为proj.myPipelines.Test.TestPipeline': 100,

这给我带来了错误。

然后我以为我可以导出模块并导入到当前模块中,pipelines.py它将从中获得参考。我__init__.pymyPipelines目录中添加了一个空然后添加,from myPipelines.Test import TestPipeline但是scrapy仍然引发错误...

Raise NameError("Module '%s' doesn't define any object named '%s'" % (module, name))
exceptions.NameError: Module 'proj.pipelines' doesn't define any object named 'TestPipeline'.
Run Code Online (Sandbox Code Playgroud)

提前谢谢了!

python scrapy scrapy-pipeline

4
推荐指数
1
解决办法
713
查看次数

Scrapy文件下载如何使用自定义文件名

对于我scrapy项目我目前使用的FilesPipeline。下载的文件以其URL的SHA1哈希作为文件名存储。

[(True,
  {'checksum': '2b00042f7481c7b056c4b410d28f33cf',
   'path': 'full/0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg',
   'url': 'http://www.example.com/files/product1.pdf'}),
 (False,
  Failure(...))]
Run Code Online (Sandbox Code Playgroud)

如何使用自定义文件名存储文件?

在上面的示例中,我希望文件名为“ product1_0a79c461a4062ac383dc4fade7bc09f1384a3910.pdf”,因此我保持唯一性,但使文件名可见。

首先,我探索了pipelines.py我的项目,但没有取得太大的成功。

import scrapy
from scrapy.pipelines.images import FilesPipeline
from scrapy.exceptions import DropItem

class MyFilesPipeline(FilesPipeline):

    def file_path(self, request, response=None, info=None):
        return request.meta.get('filename','')

    def get_media_requests(self, item, info):
        file_url = item['file_url']
        meta = {'filename': item['name']}
        yield Request(url=file_url, meta=meta)
Run Code Online (Sandbox Code Playgroud)

并在我的 settings.py

ITEM_PIPELINES = {
    #'scrapy.pipelines.files.FilesPipeline': 300
    'io_spider.pipelines.MyFilesPipeline': 200
}
Run Code Online (Sandbox Code Playgroud)

一个类似的问题已经被问,但它的目标图像,而不是文件。

任何帮助将不胜感激。

python scrapy scrapy-spider scrapy-pipeline

4
推荐指数
1
解决办法
2124
查看次数

将scrapy项目导出到不同的文件

我是从moocs刮审查喜欢这一个

从那里我获得了所有课程的详细信息,每个评论本身有 5 个项目和另外 6 个项目。

这是我拥有的课程详细信息的代码:

def parse_reviews(self, response):
    l = ItemLoader(item=MoocsItem(), response=response)
    l.add_xpath('course_title', '//*[@class="course-header-ng__main-info__name__title"]//text()')
    l.add_xpath('course_description', '//*[@class="course-info__description"]//p/text()')
    l.add_xpath('course_instructors', '//*[@class="course-info__instructors__names"]//text()')
    l.add_xpath('course_key_concepts', '//*[@class="key-concepts__labels"]//text()')
    l.add_value('course_link', response.url)
    return l.load_item()
Run Code Online (Sandbox Code Playgroud)

现在我想包括评论详细信息,每个评论另外 5 个项目。由于课程数据对于所有评论都是通用的,我想将其存储在不同的文件中,然后使用课程名称/ID 关联数据。

这是我用于评论项目的代码:

for review in response.xpath('//*[@class="review-body"]'):
    review_body = review.xpath('.//div[@class="review-body__content"]//text()').extract()
    course_stage =  review.xpath('.//*[@class="review-body-info__course-stage--completed"]//text()').extract()
    user_name =  review.xpath('.//*[@class="review-body__username"]//text()').extract()
    review_date =  review.xpath('.//*[@itemprop="datePublished"]/@datetime').extract()
    score =  review.xpath('.//*[@class="sr-only"]//text()').extract()
Run Code Online (Sandbox Code Playgroud)

我尝试使用临时解决方案,返回每个案例的所有项目,但也不起作用:

def parse_reviews(self, response):
    #print response.body
    l = ItemLoader(item=MoocsItem(), response=response)
    #l = MyItemLoader(selector=response)
    l.add_xpath('course_title', '//*[@class="course-header-ng__main-info__name__title"]//text()')
    l.add_xpath('course_description', '//*[@class="course-info__description"]//p/text()')
    l.add_xpath('course_instructors', '//*[@class="course-info__instructors__names"]//text()')
    l.add_xpath('course_key_concepts', '//*[@class="key-concepts__labels"]//text()')
    l.add_value('course_link', response.url)

    for review in response.xpath('//*[@class="review-body"]'):
        l.add_xpath('review_body', './/div[@class="review-body__content"]//text()') …
Run Code Online (Sandbox Code Playgroud)

python scrapy scrapy-pipeline

4
推荐指数
1
解决办法
1720
查看次数

Scrapy,在管道中发出http请求

假设我有一个看似这样的刮取项目

{
    name: "Foo",
    country: "US",
    url: "http://..."
}
Run Code Online (Sandbox Code Playgroud)

在管道中,我想对URL发出GET请求,并检查一些标题,如content_type和status.当标题不符合某些条件时,我想删除该项目.喜欢

class MyPipeline(object):
    def process_item(self, item, spider):
        request(item['url'], function(response) {
           if (...) {
             raise DropItem()
           }
           return item
        }, function(error){ 
            raise DropItem()
        })
Run Code Online (Sandbox Code Playgroud)

使用管道不可能闻到这样的气味.你怎么看?任何想法如何实现这一目标?

蜘蛛:

import scrapy
import json

class StationSpider(scrapy.Spider):
    name = 'station'
    start_urls = ['http://...']

    def parse(self, response):
        jsonResponse = json.loads(response.body_as_unicode())
        for station in jsonResponse:
            yield station
Run Code Online (Sandbox Code Playgroud)

scrapy scrapy-pipeline

3
推荐指数
1
解决办法
2162
查看次数