【问题标题】:Scrapy Returns 'None' after the 10th row in tableScrapy 在表中的第 10 行之后返回“无”
【发布时间】:2021-07-04 22:03:10
【问题描述】:

我尝试了许多不同的 xpath 表达式,但无法完全实现。基本上,我将获得表中前 10 行的文本,然后为接下来的 90 行获得“无”。如果我执行不同的 xpath 表达式(向我建议但我个人不完全理解的表达式),它给了我最后 90 个但不是前 10 个。起初我认为这是由于 tbody,所以我从我的 xpath 表达式中删除了它。我定位的标签的类在第 10 行之后也会发生变化,所以我不确定这是否会有所不同。我尝试插入一个“或”语句来尝试充分利用这两个 xpath,但它似乎放置不正确。请帮忙!

class CryptocurrenciesSpider(scrapy.Spider):
    name = 'cryptocurrencies'
    allowed_domains = ['www.coinmarketcap.com']

    def start_requests(self):
        yield scrapy.Request(url='https://www.coinmarketcap.com/', callback=self.parse)


#Udemy Answer. Yields last 90 with 'None' for the first 10 rows. 
     def parse(self, response):
         for row in response.xpath("//table//tr"):
             currency = row.xpath(".//td/a/span[2]/text()").get()
             if currency:
                 yield {
                     'currency': currency
                 }

#Yields the first 10 and then 'None' for the rest.
    def parse(self, response):
        for row in response.xpath(".//table//tr"):
                yield {
                'Currency': row.xpath(".//td[3]/div/a/div/div/p/text()").get()
            }

# Tried the "or" operator to no avail.
# row.xpath(".//td[3]/div/a/div/div/p/text() or .//td/a/span[2]/text()").get(
# row.xpath(".//td[3]/div/a/div/div/p/text()" or ".//td/a/span[2]/text()").get()

【问题讨论】:

    标签: python web-scraping xpath scrapy


    【解决方案1】:

    使用requestsjson 库。您不必担心元素的 xpath。您将轻松获得这些数据。像下面这样-

    req = requests.get('https://api.coinmarketcap.com/data-api/v3/cryptocurrency/listing?start=1&limit=100&sortBy=market_cap&sortType=desc&convert=USD,btc,eth&cryptoType=all&tagType=all&aux=ath,atl,high24h,low24h,num_market_pairs,cmc_rank,date_added,tags,platform,max_supply,circulating_supply,total_supply,volume_7d,volume_30d',
                headers={'Accept': 'application/json','Content-Type': 'application/json'})
    if(req.status_code == 200):
        josn2 = req.json()
        currencyDetails = josn2['data']['cryptoCurrencyList']
        print(len(currencyDetails))
        for i in currencyDetails:
            print("name : " + i.get('name'), "\t\tSymbol : "+ i.get('symbol'))
    

    您将需要以下导入 -

    import requests
    import json
    

    输出 -

    100
    name : Bitcoin      Symbol : BTC
    name : Ethereum         Symbol : ETH
    name : Binance Coin         Symbol : BNB
    name : XRP      Symbol : XRP
    name : Tether       Symbol : USDT
    name : Cardano      Symbol : ADA
    name : Polkadot         Symbol : DOT
    name : Uniswap      Symbol : UNI
    

    【讨论】:

      【解决方案2】:

      雅各布,

      事实上,解决方案已经在您手中。

      你有前十行的 xpath 表达式,以及随后的九十行。您需要做的就是将它们结合起来。

      我建议你试试管道|,它充当联合运算符。

      使用.getall() 获取全部 100 个名称的整个 xpath 可能是以下长的野兽

      //table[contains(@class, "cmc-table")]//tr/td[3]//a/div/div/p/text() | //table[contains(@class, "cmc-table")]//tr/td[3]//a/span[2]/text()
      

      或者,您可能希望遍历行/列/锚部分并仅在更改的部分上使用联合。

      祝你好运,玩得开心!

      【讨论】:

        猜你喜欢
        • 2019-03-11
        • 1970-01-01
        • 2021-11-24
        • 2014-09-10
        • 1970-01-01
        • 1970-01-01
        • 2021-03-09
        • 1970-01-01
        相关资源
        最近更新 更多