scrapy 无用的使用情形-仅限新链接

c90pui9n  于 2023-02-08  发布在  其他
关注(0)|答案(1)|浏览(127)

在一个高层次上-我想我正在尝试使用Scrapy框架像一个刮库。
我的用例是,我有一个网页,其中包含指向我想抓取的会议记录的链接,随着时间的推移,会添加更多指向会议记录的链接。
我的计划是使用一个普通的spider来抓取会议记录的链接,并通过管道/CsvItemExporter将链接列表传输到CSV。
常规蜘蛛1-网页链接到会议纪要我想刮,出口到csv:

class QuotesSpider(scrapy.Spider):
name = "easthamptontown-links"

custom_settings = {
    'ITEM_PIPELINES': {
        'themis.pipelines.ThemisPipeline': 400
    }
}

def start_requests(self):
    urls = [
        'http://easthamptontown.iqm2.com/Citizens/Calendar.aspx?From=1/1/1900&To=12/31/9999',
    ]
    for url in urls:
        yield scrapy.Request(url=url, callback=self.parse)

def parse(self, response):
    rowtops = response.xpath('//div[@class="RowTop"]')
    for meeting in rowtops:
        yield {
            'meeting': meeting.css("a[href*='Detail_Meeting']").get(),
            'files': meeting.css("a[href*='FileView']").getall(),
        }

管道1

class ThemisPipeline:
def __init__(self):
    self.files = {}

@classmethod
def from_crawler(cls, crawler):
    pipeline = cls()
    crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
    crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
    return pipeline

def spider_opened(self, spider):
    file = open('%s.csv' % spider.name, 'wb')
    self.files[spider] = file
    self.exporter = CsvItemExporter(file)
    self.exporter.start_exporting()

def spider_closed(self, spider):
    self.exporter.finish_exporting()
    file = self.files.pop(spider)
    file.close()

def process_item(self, item, spider):
    file_output = {}
    _item = ItemAdapter(item).asdict()
    if len(_item['files']) > 0:
        for filelink in _item['files']:
            parser = MyHTMLParser()
            parser.feed(filelink)
            file_output['filelink'] = parser.lsHref
            file_output['filetype'] = parser.lsData
            parser.feed(_item['meeting'])
            file_output['meetinglink'] = parser.lsHref
            file_output['meetingtitle'] = parser.lsTitle
            file_output['meetingdate'] = parser.lsData.strip()
            self.exporter.export_item(file_output)
    else:
        DropItem(item)
    return item

CsvReader()/list解析将CSV中的链接提供给start_urls中的第二个常规spider,后者使用这些链接抓取会议记录,并将/CsvItemExporter管道传输到以该链接命名的.txt文件,例如meeting123.txt
我第二次运行第一个scraper时,比较新csv中到原始csv的链接,将新csv中链接的会议纪要(而不是原始csv管道/CsvItemExporter中的链接)刮到以该链接命名的.txt文件中,例如meeting124.txt
我眼前的问题是,将抓取的minutes链接传递到管道,以minutes链接命名文件比我想象的要困难-框架似乎不适合这个。
常规spider 2-从CSV提供的URL中抓取会议记录:

class ASpider(scrapy.Spider):
name = "town-text"

custom_settings = {
    'ITEM_PIPELINES': {
        'themis.pipelines.MinutesPipeline': 400
    }
}

meetings = csvreader('./town-links.csv')
# don't override start_requests, default scrapy.Request(url=url, callback=self.parse)
start_urls = ['http://http://easthamptontown.iqm2.com/Citizens/' + meeting['filelink'] \
              for meeting in meetings \
              if 'Zoning' in meeting['meetingtitle'] and \
              'Regular Meeting' in meeting['meetingtitle'] and \
              meeting['filetype'] == 'Minutes']

def parse(self, response):
    for element in response.xpath('//div[@id="Content"]/div/*'):
        yield {
            'line': element.xpath('.//text()').getall(),
        }

管道:

class MinutesPipeline:
def __init__(self):
    self.files = {}

@classmethod
def from_crawler(cls, crawler):
    pipeline = cls()
    crawler.signals.connect(pipeline.spider_opened, signals.spider_opened)
    crawler.signals.connect(pipeline.spider_closed, signals.spider_closed)
    return pipeline

def spider_opened(self, spider):
    file = open('%s.txt' % spider.name, 'wb')
    self.files[spider] = file
    self.exporter = CsvItemExporter(file)
    self.exporter.start_exporting()

def spider_closed(self, spider):
    self.exporter.finish_exporting()
    file = self.files.pop(spider)
    file.close()

def process_item(self, item, spider):
    _item = ItemAdapter(item).asdict()
    self.exporter.export_item(_item)
    return item

我希望能够将我正在抓取的html的特定URL meeting['filelink'],-传递到项目的CSV文件名。我尝试将scrapy.Spider更改为CrawlSpider以尝试使用parse_start_url(),但选择器没有使用CrawlSpider返回任何数据。
对于Scrapy框架特有的这种用例的设计的任何想法都将受到欢迎。

lxkprmvk

lxkprmvk1#

如果你想使用url作为文件名,你所需要做的就是传递url和条目,然后用这个文件名创建一个新文件并导出它。
例如:
在parse方法中,向字典中添加一个url字段,并添加response.url作为其值。

def parse(self, response):
    for element in response.xpath('//div[@id="Content"]/div/*'):
        yield {
            'line': element.xpath('.//text()').getall(),
            'url': response.url
        }

然后在您的管道中:

def process_item(self, item, spider):
    url = item["url"]
    filename = url.split("/")[-1]
    exporter = CsvItemExporter(filename)
    text = item["text"]
    ... do text formatting if needed
    ...  export to text to file
    raise DropItem

相关问题