【问题标题】:Python: How to download Excel file from pagePython:如何从页面下载 Excel 文件
【发布时间】:2017-10-21 22:13:28
【问题描述】:
  1. 转到此网址https://www.horseracebase.com/horse-racing-results.php?year=2005&month=3&day=15(用户名 = TrickyBen | 密码 = TrickyBen123)
  2. 请注意,有一个下载 Excel 按钮(红色)
  3. 我想下载 excel 文件并将其转换为 pandas 数据框。我想以编程方式进行(即从脚本中,而不是通过手动点击网站)。我该怎么做?

此代码将使您以 TrickyBen 身份登录,并向网站 API 发出请求...

导入请求 从 lxml 导入 html 从请求导入会话 将熊猫导入为 pd 导入shutil

raceSession = Session()

LoginDetails = {'login': 'TrickyBen', 'password': 'TrickyBen123'}

LoginUrl = 'https://www.horseracebase.com/horse-racing-results.php?year=2005&month=3&day=15/horsebase1.php'
LoginPost = raceSession.post(LoginUrl, data=LoginDetails)

RaceUrl = 'https://www.horseracebase.com/excelresults.php'
RaceDataDetails =  {"user": "41495", "racedate": "2005-3-15", "downloadbutton": "Excel"}

PostHeaders = {"Content-Type": "application/x-www-form-urlencoded"}
Response = raceSession.post(RaceUrl, data=RaceDataDetails, headers=PostHeaders)

Table = pd.read_table(Response.text)

Table.to_csv('blahblah.csv')

如果你检查元素,你会注意到相关元素看起来像这样......

<form action="excelresults.php" method="post">
    <input type="hidden" name="user" value="41495">
    <input type="hidden" name="racedate" value="2005-3-15">
    <input type="submit" class="downloadbutton" value="Excel">
</form>

我收到此错误消息...

Traceback (most recent call last):
  File "/Users/Alex/Desktop/DateTest/hrpull.py", line 20, in <module>
    Table = pd.read_table(Response.text)
  File "/Library/Python/2.7/site-packages/pandas/io/parsers.py", line 562, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/Library/Python/2.7/site-packages/pandas/io/parsers.py", line 315, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/Library/Python/2.7/site-packages/pandas/io/parsers.py", line 645, in __init__
    self._make_engine(self.engine)
  File "/Library/Python/2.7/site-packages/pandas/io/parsers.py", line 799, in _make_engine
self._engine = CParserWrapper(self.f, **self.options)
  File "/Library/Python/2.7/site-packages/pandas/io/parsers.py", line 1213, in __init__
self._reader = _parser.TextReader(src, **kwds)
  File "pandas/parser.pyx", line 358, in pandas.parser.TextReader.__cinit__ (pandas/parser.c:3427)
  File "pandas/parser.pyx", line 628, in pandas.parser.TextReader._setup_parser_source (pandas/parser.c:6861)
IOError: File race_date race_time   track   race_name       race_restrictions_age   race_class  major   race_distance   prize_money     going_description   number_of_runners   place   distbt  horse_name  stall       trainer horse_age   jockey_name jockeys_claim   pounds  odds    fav     official_rating comptime    TotalDstBt  MedianOR    Dist_Furlongs       placing_numerical   RCode   BFSP    BFSP_Place  PlcsPaid    BFPlcsPaid      Yards   RailMove    RaceType    
"2005-03-15"    "14:00:00"  "Cheltenham"    "Letheby & Christopher Supreme Novices Hurdle " "4yo+"  "Class 1"   "Grade 1"   "2m˝f " "58000" "Good"  "20"    "1st"       "Arcalis"   "0" "Johnson, J Howard" "5" "Lee, G"    "0" "161"   "21"        "136"   "3 mins 53.00s"     "121.5" "16.5"  "1" "National Hunt" "0" "0" "3" "0" "0" "0" "Novices Hurdle"
"2005-03-15"    "14:00:00"  "Cheltenham"    "Letheby & Christopher Supreme Novices Hurdle " "4yo+"  "Class 1"   "Grade 1"   "2m˝f " "58000" "Good"  "20"    "2nd"   "6" "Wild Passion (GER)"    "0" "Meade, Noel"   "5" "Carberry, P"   "0" "161"   "11"        "0" "3 mins 53.00s" "6" "121.5" "16.5"  "2" "National Hunt" "0" "0" "3" "0" "0" "0" "Novices Hurdle"

【问题讨论】:

  • 所以你想下载信息而不下载文件?
  • 嘿 - 我想以编程方式下载文件。 IE。不仅仅是手动将文件下载到我的桌​​面,然后使用 read_csv 将文件读入 DataFrame。当然,read_csv 会将文件放入 DataFrame,但我想从脚本中访问文件。我希望这是有道理的?

标签: python excel


【解决方案1】:

我认为您可以在另一个网页中查看要下载的数据,例如,通过单击“我的系统 (v4)”。如果你能做到这一点,那么你可以使用 urllib.request.urlretrieve 下载该页面。然后你可以使用 html.parser.HTMLParser 来解析数据并按照你的意愿去做。

【讨论】:

    【解决方案2】:

    如果您查看在表单操作上调用的 api,您会看到您必须向该 url 发出发布请求:

    https://www.horseracebase.com/excelresults.php
    

    带有以下参数:

    data = {
        "user": "41495", # looks like this varies with login, so update in case you change your login id
        "racedate": "2005-3-15",
        "downloadbutton": "Excel"
    }
    

    你可以这样做:

    response = raceSession.post(reqUrl, json=data)
    

    如果这不起作用,请尝试将标头添加到请求中,例如:headers=postHeaders。例如。在这种情况下,您应该设置内容类型标头,因为您正在发送表单编码数据,所以:

    headers = {"Content-Type": "application/x-www-form-urlencoded"} 
    

    阅读this 了解有关如何将 excel 保存到文件的更多信息

    这是 Postman 中此请求的响应,所以看起来您不需要任何额外的标头,除了 content-type

    编辑

    这是你需要做的:

    raceSession = Session()
    
    RaceUrl = 'https://www.horseracebase.com/excelresults.php'
    RaceDataDetails =  {"user": "41495", "racedate": "2005-3-15", "downloadbutton": "Excel"}
    
    PostHeaders = {"Content-Type": "application/x-www-form-urlencoded"}
    Response = raceSession.post(RaceUrl, data=RaceDataDetails, headers=PostHeaders)
    # from StringIO import StringIO #for python 2.x
    #import StringIO #for python 3.x
    Table = pd.read_table(StringIO(Response.text)) 
    

    【讨论】:

    • 大家好,谢谢。我取得了一些进展,但我的代码不起作用。你能看看我做错了什么吗?
    • raceSession = Session() LoginDetails = {'login': 'TrickyBen', 'password': 'TrickyBen123'} LoginUrl = 'horseracebase.com/…' LoginPost = raceSession.post(LoginUrl, data=LoginDetails ) RaceUrl = 'horseracebase.com/excelresults.php' RaceDataDetails = {"user": "41495", "racedate": "2005-3-15", "downloadbutton": "Excel"} PostHeaders = {"Content-Type": "application /x-www-form-urlencoded"} 响应 = raceSession.post(RaceUrl, json=RaceDataDetails, headers=PostHeaders) 表 = pd.read_table(Response)
    • @BennyBoe 你能把这个添加到你的问题中
    • 您将 Response 直接传递给 pandas,您应该先将其保存到文件中,然后尝试读取它。查看答案以获取有关保存到文件的更多信息。
    • 谢谢我已经更新了上面答案中的代码。我现在收到的错误消息如下...

      您必须拥有有效的 HorseRaceBase 会员资格才能访问此功能。 立即注册免费试用

      我不知道为什么会收到此消息,因为我已经登录了同一个会话。
    猜你喜欢
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多