首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >response.xpath().extract()返回字符串列表而不是DOM片段

response.xpath().extract()返回字符串列表而不是DOM片段
EN

Stack Overflow用户
提问于 2018-12-08 05:57:21
回答 1查看 0关注 0票数 0

我问这个的唯一原因是因为我宁愿用response.xpath而不是response.css

这是我编写的脚本的工作副本,使用response.css翻译的脚本response.xpath

代码语言:javascript
复制
import scrapy

class RentalsCrawler(scrapy.Spider):
    name = "rentals"
    allowed_domains = [
        'craigslist.org',
        'kajiji.ca'
    ]
    custom_settings = {
        'DOWNLOAD_DELAY': 2,
        'CONCURRENT_REQUESTS_PER_DOMAIN': 2,
    }
    handle_httpstatus_list = [404]
    def start_requests(self):
        start = 0
        nopgs = 1
        pages = []
        for i in range(0, nopgs):
            i = i * 120 + start
            pages.append('https://vancouver.craigslist.ca/search/apa?s=' + str(i))
        for page in pages:
            yield scrapy.Request(url=page, callback=self.parse)
    def parse(self, response):
        for li in response.css('ul.rows li p span.result-meta'):
            prc = li.css('span.result-price::text').extract_first()
            sqf = li.css('span.housing::text').extract_first()
            loc = li.css('span.result-hood::text').extract_first()
            objct = { 'prc': prc }
            if sqf:
                objct['sqf'] = sqf
            if loc:
                objct['loc'] = loc
            yield objct

问题是以下代码返回一个字符串列表而不是DOM片段,我可以使用XPath进一步解析它。

代码语言:javascript
复制
def parse(self, response):
    dad_path = '//ul[@class="rows"]/li/p/span[@class="result-meta"]'
    dad_resp = response.xpath(dad_path).extract()
    ...

上面的代码以下列格式生成输出,其中每个dict元素中的值是一个巨大的字符串,而不是可以进一步解析的DOM片段。

代码语言:javascript
复制
[
  {
    "a": "<span class=\"result-meta\">\n                <span class=\"result-price\">$3750</span>\n\n                <span class=\"housing\">\n                    4br -\n                    2150ft<sup>2</sup> -\n                </span>\n\n                <span class=\"result-hood\"> (DUNDARAVE)</span>\n\n                <span class=\"result-tags\">\n                    pic\n                    <span class=\"maptag\" data-pid=\"6611144029\">map</span>\n                </span>\n\n                <span class=\"banish icon icon-trash\" role=\"button\">\n                    <span class=\"screen-reader-text\">hide this posting</span>\n                </span>\n\n            <span class=\"unbanish icon icon-trash red\" role=\"button\" aria-hidden=\"true\"></span>\n            <a href=\"#\" class=\"restore-link\">\n                <span class=\"restore-narrow-text\">restore</span>\n                <span class=\"restore-wide-text\">restore this posting</span>\n            </a>\n\n        </span>"
  }
  ...

因此可以说下面的代码“出现故障”。

代码语言:javascript
复制
for span in dad_resp:
    prc_path = '//span[@class="result-meta"]/span[@class="result-price"]/text()'
    prc_resp = response.xpath(prc_path).extract_first()
    yield {
        'prc': prc_resp
    }

并产生这样的输出。

代码语言:javascript
复制
[
  {
    "prc": "$3750"
  },
  {
    "prc": "$3750"
  },
  {
    "prc": "$3750"
  },
  ...

然而,如果您把response.xpath(prc_path).extract_first()改为response.xpath(prc_path).extract(),它确实提取所有不同的价格,而不是一遍又一遍地重复相同的价格。但是,它将所有价格汇总到一个列表中。我想做的是将每件商品的价格,平方英尺等等分成不同的单词。

知道怎么做吗?我究竟做错了什么?!

EN

回答 1

Stack Overflow用户

发布于 2018-12-08 15:49:47

代码语言:txt
复制
import scrapy

class RentalsCrawler(scrapy.Spider):
    name = "rentals"

    allowed_domains = [
        'craigslist.org',
        'kajiji.ca'
    ]

    custom_settings = {
        'DOWNLOAD_DELAY': 2,
        'CONCURRENT_REQUESTS_PER_DOMAIN': 2,
    }

    handle_httpstatus_list = [404]

    def start_requests(self):
        start = 0
        nopgs = 1

        for i in range(0, nopgs):
            url = 'https://vancouver.craigslist.ca/search/apa?s=%s' % (i * 120 + start)

            yield scrapy.Request(url)

    def parse(self, response):
        for li in response.xpath('//ul[@class="rows"]/li//span[@class="result-meta"]'):

            prc = li.xpath('//span[@class="result-price"]/text()').extract_first(default='')
            sqf = li.xpath('//span[@class="housing"]/text()').extract_first(default='')
            loc = li.xpath('//*[@class="result-hood"]/text()').extract_first(default='')

            yield {
                'prc': prc,
                'loc': loc,
                'sqf': sqf,
            }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100003034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档