0

我试图找出处理以下数据的最佳方法。我正在抓取一个站点并使用文本 (.prn) 文件(用于打印的文件,这是包含我想要的数据的文件,我认为这会比 Adob​​e Acrobat 文件更好)来收集数据。我的问题是当我将数据带入 python 时:数据只是在屏幕上一次一个字母垂直向下出现,所以即使有多行,这些数据也只是在一列中流入。我想知道是否有人会知道如何以更“传统”的方式输入数据,我可以引入 row[0]、row [1] 等......这是我的代码以防万一(你还可以看到我尝试过的其他一些功能)。

import os
import urllib
import urllib2
import string
import sys
import os
from bs4 import BeautifulSoup
import csv
import mechanize
from numpy import*
import datetime
import traceback
from pylab import*
site="http://www.treasurydirect.gov/govt/reports/pd/mspd/mspd.htm"

br = mechanize.Browser()
br.set_handle_equiv(False)
br.open(site)
print 'br.title',br.title()
allforms = list(br.forms())
br.form = allforms[0]
br.follow_link(text_regex="February", nr=0)
#br.click_link(text='February', nr=0) # this works to

#next page
print br.title()
allforms = list(br.forms())
print allforms
br.form = allforms[0]   
getstuff=br.click_link(text="Text (.prn)", nr=0) # this works to
#getstuff= br.click_link(text="Adobe Acrobat (.pdf)", nr=0)  Adobe Acrobat (.pdf)

br.open(getstuff)


csvData=br.response().read() # use read to BeautifulSoup(x)
#site = BeautifulSoup(csvData)
#print site
for row in csvData:
 print row[0]

以下是文本 (.prt) 文件所在的确切网站页面: http ://www.treasurydirect.gov/govt/reports/pd/mspd/2013/2013_feb.htm

我正在尝试处理摘要下的文本(.prn)文件中的数据。请就处理数据的最佳方式提供建议。

我正在使用 python27、mechanize、beautiful soup 和 urllib

4

1 回答 1

0

用漂亮的汤读取文本文件似乎会给您返回 csvData 中的单个字符串,而不是您期望的行列表。因此,对字符串进行迭代会在每个迭代步骤中返回一个字符。这就是为什么您的文本似乎转换为单列的原因。

首先,你似乎根本不需要漂亮的汤!您正在检索文本文件,而不是 HTML 文件。Beautiful Soup是一个 HTML/XML 解析器。mechanize对我来说似乎也没有必要(我已经看过你之前的问题,但实际上,你不需要解析 HTML 页面来发现链接,因为你已经知道最终的 url)。

对我来说,您应该将算法分为三个部分:

  • 将文本检索为行列表
  • 删除不必要的行
  • 格式化您的行以适合您的目的

您的问题似乎主要与第一部分有关,但是由于您还询问有关如何检索最终数据的建议,我想您也需要另外两个:)

这是我的建议:让我们开始定义三个函数,一个用于算法的每个部分......

import urllib2, re

def get_data_text(month, year):
    """given a month and a year, this method returns the raw data file (as a list of rows)"""
    url_pattern = 'http://www.treasurydirect.gov/govt/reports/pd/mspd/{year:4d}/opds{month:02d}{year:4d}.prn'
    url = url_pattern.format(month=month, year=year)
    source = urllib2.urlopen(url)
    data = source.readlines()
    source.close()
    return data


def keep_only_interesting_rows(data, interesting_rows):
    """filter data rows in order to keep only the ones that start with strings in interesting_rows list"""
    return [line for line in data if any([line.strip().startswith(ir) for ir in interesting_rows])]


def convert_data_to_dict(data):
    """converts every row in data to a dictionary element """
    return {re.sub('\.*\s*$', '', el[0:46]).strip():(int(el[47:63].replace(',','')), int(el[69:90].replace(',','')), int(el[95:115].replace(',',''))) for el in data}

所以现在我已经定义了三个函数,一个用于我提出的解决方案中的每个部分。


如何使用这些功能?这是一个例子:

interesting_rows = ['Bills', 'Notes', 'Total Public Debt Outstanding']  # add the initial part of any row you are interested at (without leading spaces)

mytext = get_data_text(2, 2013)  # gets the text for feb, 2013 as rows
data = keep_only_interesting_rows(mytext, interesting_rows)  # filter rows
final_data = convert_data_to_dict(data)  # convert remaining rows into a dict

print final_data
print final_data['Bills'][2]  # this gives you the third column


# >>> {'Notes': (7416574, 5888, 7422462), 'Bills': (1738404, 3546, 1741950), 'Total Public Debt Outstanding': (11822436, 4864853, 16687289)}
# >>> 1741950


如果您愿意,无论出于何种原因,访问初始文本文件(.prn 文件)中的精确行,您可以键入:

mytext = get_data_text(9, 2012)  # this time let's get the text for September, 2012 
print mytext[0]

返回:

    MONTHLY STATEMENT OF THE PUBLIC DEBT
于 2013-03-21T23:28:07.167 回答