【问题标题】:Trying to scrape some things using Scrapy, but csv file is empty , whats the problem?尝试使用 Scrapy 抓取一些东西,但是 csv 文件是空的,这是什么问题?
【发布时间】:2021-10-12 21:39:31
【问题描述】:

这是我的代码,我试图从 findalocalvet.com 抓取一些数据,但是当我运行蜘蛛时,创建的 .csv 文件是空的,有什么问题?

import scrapy


class VetSpider(scrapy.Spider):
    name = 'vet_project'
    start_urls = ['http://findalocalvet.com/Find-a-Veterinarian.aspx/']

    def parse(self, response):
        for link in response.css('#SideByCity .itemresult a::attr(href)').getall():
            link = response.urljoin(link)
            yield scrapy.Request(link, callback=self.parse_city)


    def parse_city(self, response):
        for link in response.css('.org::attr(href)').getall():
            link = response.urljoin(link)
            yield scrapy.Request(link, callback=self.parse_clinic)
        next_link = response.css('a.dataheader:contains("Next")::attr(href)').getall()
        if next_link:
            next_link = response.urljoin(next_link)
            yield scrapy.Request(next_link, callback=self.parse_city)


    def parse_clinic(self, response):
        yield {
            'Name': response.css('.Results-Header h1::text').get(),
            'City': response.css('.locality::text').get(),
            'State': response.css('.region::text').get(),
            'Phone': response.css('.Phone::text').get(),
            'Link': response.url,

        }

【问题讨论】:

  • 首先你可以使用print()查看你在变量中得到了什么以及执行了哪部分代码——也许它永远不会执行parse_clinic()。第二:您应该检查页面是否使用 JavaScript 向 HTML 添加元素 - scrapy 无法运行 JavaScript。
  • 也许你应该使用yield response.follow(link,...) 而不是joinRequest
  • 我在函数 parse_clinic() 中使用 print("parse_clinic") 运行您的代码,但它从不显示它 - 所以它永远不会得到 css('.org::attr(href)')。顺便说一句:当我尝试在浏览器中打开页面时,它会显示 redirection loop 的问题 - 似乎服务器无法正常工作,也许这是问题。
  • @furas response.follow 在这里不起作用,你会得到'findalocalvet.com/Find-a-Veterinarian.aspx/some_link.aspx',你自己试试吧。
  • @SuperUser 如果您从start_urls 中删除最后一个/,则response.follow 可以正常工作。坦率地说,我很惊讶 OP 将 / 放在 url 的末尾,然后在我开始测试代码之前立即将其删除:)

标签: python web-scraping scrapy


【解决方案1】:

“response.urljoin”是错误的。要么使用 urllib.parse.urljoin('http://findalocalvet.com/', link),要么只连接字符串:

import scrapy


class VetSpider(scrapy.Spider):
    name = 'vet_project'
    start_urls = ['http://findalocalvet.com/Find-a-Veterinarian.aspx/']
    base_url = 'http://findalocalvet.com/'

    def parse(self, response):
        for link in response.css('#SideByCity .itemresult a::attr(href)').getall():
            link = self.base_url + link
            yield scrapy.Request(link, callback=self.parse_city)

    def parse_city(self, response):
        for link in response.css('.org::attr(href)').getall():
            link = self.base_url + link
            yield scrapy.Request(link, callback=self.parse_clinic)
        next_link = response.css('a.dataheader:contains("Next")::attr(href)').get()
        if next_link:
            next_link = self.base_url + next_link
            yield scrapy.Request(next_link, callback=self.parse_city)

    def parse_clinic(self, response):
        yield {
            'Name': response.css('.Results-Header h1::text').get(),
            'City': response.css('.locality::text').get(),
            'State': response.css('.region::text').get(),
            'Phone': response.css('.Phone::text').get(),
            'Link': response.url,
        }

(此外,'getall()' 将返回一个列表,因此请使用 'next_url[0]',或者更好地将其替换为 'get()')

【讨论】:

    猜你喜欢
    • 2019-11-24
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 2013-10-11
    • 2018-04-09
    • 2013-05-29
    • 2012-01-25
    • 2011-04-27
    相关资源
    最近更新 更多