使用Scrapy从网站查找和下载pdf文件

时间:2016-03-21 15:55:14

标签: python scrapy

我的任务是使用Scrapy从网站上提取pdf文件。我不是Python的新手,但Scrapy对我来说是一个新手。我一直在试验控制台和一些基本的蜘蛛。我找到并修改了这段代码:

import urlparse
import scrapy

from scrapy.http import Request

class pwc_tax(scrapy.Spider):
    name = "pwc_tax"

    allowed_domains = ["www.pwc.com"]
    start_urls = ["http://www.pwc.com/us/en/tax-services/publications/research-and-insights.html"]

    def parse(self, response):
        base_url = "http://www.pwc.com/us/en/tax-services/publications/research-and-insights.html"
        for a in response.xpath('//a[@href]/@href'):
            link = a.extract()
            if link.endswith('.pdf'):
                link = urlparse.urljoin(base_url, link)
                yield Request(link, callback=self.save_pdf)

    def save_pdf(self, response):
        path = response.url.split('/')[-1]
        with open(path, 'wb') as f:
            f.write(response.body)

我使用

在命令行运行此代码
scrapy crawl mySpider

我一无所获。我没有创建scrapy项目,因为我想抓取并下载文件,没有元数据。我很感激任何帮助。

1 个答案:

答案 0 :(得分:21)

蜘蛛逻辑似乎不正确。

我快速浏览了一下您的网站,似乎有几种类型的网页:

  1. http://www.pwc.com/us/en/tax-services/publications/research-and-insights.html首页
  2. 特定文章的网页,例如可以从第1页
  3. 导航的http://www.pwc.com/us/en/tax-services/publications/insights/australia-introduces-new-foreign-resident-cgt-withholding-regime.html
  4. 实际PDF位置,例如可以从第2页
  5. 导航的http://www.pwc.com/us/en/state-local-tax/newsletters/salt-insights/assets/pwc-wotc-precertification-period-extended-to-june-29.pdf

    因此,正确的逻辑如下:首先获得#1页面,然后获取#2页面,我们可以下载#3页面。
    但是,您的蜘蛛尝试直接从#1页面提取#3页面的链接。

    <强>编辑:

    我已经更新了您的代码,以及实际运作的内容:

    import urlparse
    import scrapy
    
    from scrapy.http import Request
    
    class pwc_tax(scrapy.Spider):
        name = "pwc_tax"
    
        allowed_domains = ["www.pwc.com"]
        start_urls = ["http://www.pwc.com/us/en/tax-services/publications/research-and-insights.html"]
    
        def parse(self, response):
            for href in response.css('div#all_results h3 a::attr(href)').extract():
                yield Request(
                    url=response.urljoin(href),
                    callback=self.parse_article
                )
    
        def parse_article(self, response):
            for href in response.css('div.download_wrapper a[href$=".pdf"]::attr(href)').extract():
                yield Request(
                    url=response.urljoin(href),
                    callback=self.save_pdf
                )
    
        def save_pdf(self, response):
            path = response.url.split('/')[-1]
            self.logger.info('Saving PDF %s', path)
            with open(path, 'wb') as f:
                f.write(response.body)