代码之家  ›  专栏  ›  技术社区  ›  Richard Smith

从文本文件复制数据并将其插入URL

  •  2
  • Richard Smith  · 技术社区  · 6 年前

    背景:

    我正在构建一个程序,从互联网上获取天气数据,并将其作为GUI的一部分显示给用户。用户将输入他们的位置详细信息,特别是他们的邮政编码或邮政编码、城市或城镇、纬度和经度。该程序将这四条信息存储到文本文件中,这样用户每次想要请求天气数据时都可以读取详细信息,而无需在每次请求时输入这些详细信息。这个问题涉及的模块是urllib和BeautifulSoup。

    import urllib.request
    from bs4 import BeautifulSoup
    

    问题是:

    我成功地将用户详细信息存储到文本文件中,并从中读取。插入数据的代码如下所示:

    userPostcode = postcodeEntry.get()
    userCity     = cityEntry.get()
    userLat      = latitudeEntry.get()
    userLong     = longitudeEntry.get()
    file = open("LocationInfo.txt", 'w')
    file.write(str(userPostcode) + "\n")
    file.write(str(userCity) + "\n")
    file.write(str(userLat) + "\n")
    file.write(str(userLong)+ "\n")
    file.close()
    

    文本文件中的数据结构如下所示:

    SK15 IJF
    SOME TOWN
    54.25
    -122.312
    

    从文本文件读取的代码如下所示:

    f=open('LocationInfo.txt')
    line=f.readlines()
    Post = line[0]
    Town = line[1]
    Lat  = line[2]
    Long = line[3]
    f.close()
    

    我将这些变量的值插入URL的方式是使用以下方法:

    page_url = "https://www.metcheck.com/WEATHER/now_and_next.asp? 
    zipcode=%s+%s&lat=%s&lon=%s" % (Post, Town, Lat, Long)
    soup = BeautifulSoup(urllib.request.urlopen(page_url), "lxml")
    

    *请注意,在实际程序中,url都在一行上。

    错误:

    我收到的错误是:

    Exception in Tkinter callback
    Traceback (most recent call last):
    Python\Python36-32\lib\http\client.py", line 279, in _read_status
    raise BadStatusLine(line)
    http.client.BadStatusLine: <html>
    

    只有在尝试使用分配给文本文件中数据的变量名,并尝试使用%方法将其插入URL时,才会发生此错误。当我直接在URL字符串中输入值,而不是使用变量名时,会出现预期的结果。因此,我有理由相信问题与变量本身和值有关,而不是与有效的实际数据有关。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Alex Osheter    6 年前

    要解决换行符问题,请考虑将信息也存储为JSON文件。这将使解析更加容易,这就是它的设计目的!它还允许您在将来向程序添加功能。

    这与你的问题关系不大,OP.但不建议从网页中删除HTML数据。我不知道如何解析数据,但如果网站的设计发生变化,可能会影响解析器。

    更好的方法是寻找API。哪个metcheck . 更多信息 here . 更准确地说, this (查看JSON URL下)。

    import json
    
    json_data = ""
    with open("test.json") as json_file:
        json_data = json.load(json_file)
    
    print(json_data["zipcode"]) # prints the zip code.
    

    站点示例:

    import requests
    import json
    json_data = requests.get("http://ws1.metcheck.com/ENGINE/v9_0/json.asp?lat=51.8&lon=-0.1&lid=60357&Fc=No").text
    first_day = json.loads(json_data)["metcheckData"]["forecastLocation"]["forecast"][0]
    print(first_day["weekday"]) # print the first day of the first forecast.
    print(first_day["temperature"]) # print the temperature of the first day.
    
        2
  •  1
  •   jujuBee    6 年前

    你可以 requests 图书馆

    import requests
    
    page_url = "https://www.metcheck.com/WEATHER/now_and_next.asp? 
    zipcode=%s+%s&lat=%s&lon=%s" % (Post, Town, Lat, Long)
    
    r = requests.get(page_url)
    
        3
  •  0
  •   Richard Smith    6 年前

    找到了一种方法:

    使用。格式化,将值插入URL字符串,然后将其作为urllib的参数传递。要求urlopen(*args)

    file = open("LocationInfo.txt", 'r')
    line = file.readlines()
    savedDetails = line[0]
    
    listDetails = savedDetails.split(',')
    url= "https://www.metcheck.com/WEATHER/now_and_next.asp?zipcode={}&lat= 
    {}&lon={}"
    page_url = url.format(listDetails[1], listDetails[2], listDetails[3])
    print(page_url)
    soup = BeautifulSoup(urllib.request.urlopen(page_url), "lxml")
    

    我认为发生错误的原因是因为这些值被写入文本文件,并且在每个条目的末尾使用了“换行符”。这意味着当URL试图格式化文本文件中的数据时,它也会读取换行符条目,这意味着URL无效。我通过简单地更改代码来解决这个问题,以便将数据写入文本文件的一行,并用逗号分隔。然后。split函数用于分离数据的每个部分,以便将其形成一个列表,然后将列表中的每个元素简单地传递到URL中。很有技巧,但它确实起到了作用。

    file = open("LocationInfo.txt", 'w')
    file.write(str(userPostcode + ","))
    file.write(str(userCity + ","))
    file.write(str(userLat + ","))
    file.write(str(userLong+ ","))
    file.close()