8

我在 Django Architecture 中有这个 utils.py 文件:

def range_data(ip):
    r = []
    f = open(os.path.join(settings.PROJECT_ROOT, 'static', 'csv ', 
                          'GeoIPCountryWhois.csv'))
    for num,row in enumerate(csv.reader(f)):
        if row[0] <= ip <= row[1]:
            r.append([r[4]])
            return r
        else:
            continue
    return r

这里的 ip 参数只是 IPv4 地址,我使用的是开源 MAXMINDGeoIPCountrywhois.csv文件。

的一些起始内容GeopIOCountrywhois.csv

"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
"1.0.8.0","1.0.15.255","16779264","16781311","CN","China"
"1.0.16.0","1.0.31.255","16781312","16785407","JP","Japan"
"1.0.32.0","1.0.63.255","16785408","16793599","CN","China"
"1.0.64.0","1.0.127.255","16793600","16809983","JP","Japan"
"1.0.128.0","1.0.255.255","16809984","16842751","TH","Thailand"

我也读过这个问题,但没有发现这么多可以理解的。你能帮我解决这个错误吗?

根据我在 utils 中的方法,我正在检查IP该方法的参数地址的国家名称。

4

3 回答 3

14

今天早些时候有类似的问题,一行中缺少一个结束引号,解决方案是指示reader对引号字符(quoting=csv.QUOTE_NONE)不进行特殊处理。

于 2013-01-05T22:01:50.947 回答
8
  1. 您可以通过删除换行符来预处理 csv,如下所示。

    import csv
    
    content = open("GeoIPCountryWhois.csv", "r").read().replace('\r\n','\n')
    
    with open("GeoIPCountryWhois2.csv", "w") as g:
        g.write(content)
    

    然后将 GeoIPCountryWhois2 用于 csv 阅读器。

  2. 使用 lineterminator 的疯狂猜测可能会解决您的问题

    for num,row in enumerate(csv.reader(f,lineterminator='\n'))
    

    另见:http ://docs.python.org/lib/csv-fmt-params.html

于 2012-07-06T13:18:26.823 回答
3

您必须将文件作为二进制文件打开:

def range_data(ip):
    r = []
    f = open(os.path.join(settings.PROJECT_ROOT, 'static', 'csv ', 
                          'GeoIPCountryWhois.csv'), 'rb')
    for num,row in enumerate(csv.reader(f)):
        # Your things.

注意'rb'那里的模式;否则文件可能会以本机行结尾打开,并且 CSV 阅读器不能很好地处理各种形式。GeoIPCountryWhois.csv当然,下载的副本有干净的\n行尾。

这是为.reader() 方法记录的:

如果 csvfile 是文件对象,则必须在不同的平台上使用 'b' 标志打开它。

但是,如果您的 csv 文件严重损坏,以至于在意外的地方仍然包含意外的换行符,请使用此file子类作为权宜之计:

class CleanlinesFile(file):
    def next(self):
        line = super(CleanlinesFile, self).next()
        return line.replace('\r', '').replace('\n', '') + '\n'

这个类保证在返回的结果中除了最后一个字符之外没有换行符(就像 csv 模块想要的那样)。用它代替open调用;在这种情况下,'rb'模式修饰符变为可选:

def range_data(ip):
    r = []
    f = CleanlinesFile(os.path.join(settings.PROJECT_ROOT, 'static', 'csv ', 
                          'GeoIPCountryWhois.csv'))
    for num,row in enumerate(csv.reader(f)):
        # Your things.
于 2012-07-06T13:31:56.447 回答