【问题标题】:Web-scraping Historical Bitcoin Data from coinmarketcap.com从 coinmarketcap.com 网络抓取历史比特币数据
【发布时间】:2018-03-25 20:00:27
【问题描述】:

我在用漂亮的汤在网上抓取一些数据时遇到了一些问题,我想知道你们中的任何抓取器专家是否可以给我一些指导。

这是我要抓取的确切网页: https://coinmarketcap.com/currencies/bitcoin/historical-data/?start=20130428&end=20171013

具体来说,我想获取历史价格表并以某种方式将信息提取到 DataFrame 中。但首先我需要在原始 html 中实际找到它。

import requests
from bs4 import BeautifulSoup

data = requests.get('https://coinmarketcap.com/currencies/bitcoin/historical-data/?start=20130428&end=20171013') 

soup = BeautifulSoup(data._content, 'html.parser')

很遗憾,我遇到了编码错误

UnicodeEncodeError: 'ascii' codec can't encode character '\xa0' in position 22075: ordinal not in range(128)

在将原始 html 传递给漂亮的汤之前,有没有办法基本上只是去掉所有无法编码的字符?

【问题讨论】:

    标签: python web-scraping beautifulsoup


    【解决方案1】:

    BeautifulSoup(data._content.decode('utf-8'))

    先尝试解码utf-8

    如果还是有问题,可以告诉解码器忽略错误:

    BeautifulSoup(data._content.decode('utf-8', 'ignore))

    【讨论】:

      【解决方案2】:

      这并不能直接回答您的问题 - 我不确定如何将 lxml 设置为解析器,但我成功找到并提取了数据 - 请注意,有一种方法可以在 BS 中使用 LXML,但我直接使用 LXML 而不是访问它通过BS

      from lxml import html
      import requests
      
      
      data = requests.get('https://coinmarketcap.com/currencies/bitcoin/historical-data/?start=20130428&end=20171013').content
      tree = html.fromstring(data)
      # note I did not want to sort out the logic to find the table so I cheated
      # and selected the table with a specific data value
      mytable = tree.xpath('//td[contains(.,"4829.58")]/ancestor::table')[0]
      for e in mytable.iter(tag='tr'):
          e.text_content()
      
          '\n                        Date\n                        Open\n                        High\n                        Low\n                        Close\n                        Volume\n                        Market Cap\n                    '
         '\n                        Oct 12, 2017\n                        4829.58\n                        5446.91\n                        4822.00\n                        5446.91\n                        2,791,610,000\n                        80,256,700,000\n                        '
      

      我认为 unicode 问题在树的更远处(除了您要查找的表之外的某个元素),因此我从表中获取数据或将结果写入文件没有问题。

      【讨论】:

        【解决方案3】:

        这是一个对我有用的解决方案(此示例适用于 Python 3):

        # use urllib to get HTML data
        url = "https://coinmarketcap.com/historical/20201206/"
        contents = urllib.request.urlopen(url)
        bytes_str = contents.read()
        
        # decode bytes string
        data_str = bytes_str.decode("utf-8")
        
        # crop the raw JSON string out of the website HTML
        start_str = '"listingHistorical":{"data":'
        start = data_str.find(start_str)+len(start_str)
        end = data_str.find(',"page":1,"sort":""')
        cropped_str = data_str[start:end]
        
        # create a Python list from JSON string
        data_list = json.loads(cropped_str)
        print ("total cryptos:", len(data_list))
        
        # iterate over the list of crypto dicts
        for i, item in enumerate(data_list):
        
            # pretty print all cryptos with a high rank
            if item["cmc_rank"] < 30:
                print (json.dumps(item, indent=4))
        
        

        要从另一个日期获取另一个数据,只需将 URL 中的 20201206 部分替换为首选日期(例如,使用 20210110 代替 2021 年 1 月 10 日)。

        【讨论】:

          猜你喜欢
          • 2022-01-02
          • 1970-01-01
          • 2022-01-17
          • 1970-01-01
          • 1970-01-01
          • 2021-12-19
          • 2021-02-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多