复制文本文件中的数据,并将其插入URL

时间:2018-03-24 21:46:24

标签: python python-3.x urllib

背景

我正在构建一个从互联网上抓取天气数据的程序,并将其作为GUI的一部分显示给用户。用户将输入他们的位置详细信息,特别是他们的PostCode或ZipNumber,城市或城镇,纬度和经度。程序将这四个信息存储到文本文件中,这样每次用户想要请求天气数据时都可以读取详细信息,而不必在每个请求中输入这些细节。这个问题涉及的模块是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()

textfile中的数据结构如下所示:

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")

*请注意,实际程序中的网址都在一行。

错误:

我收到的错误是:

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 个答案:

答案 0 :(得分:1)

您可以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)

答案 1 :(得分:1)

要解决换行问题,请考虑将信息也存储为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 :(得分:0)

找到了一种方法:

使用.format,将值插入URL字符串,然后将其作为urllib.request.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")

我相信错误发生的原因是因为使用&#39;换行符&#39;将值写入文本文件。在每个条目的末尾使用。这意味着当URL尝试格式化文本文件中的数据时,它也会读取换行符,这意味着URL无效。我通过简单地更改代码来解决这个问题,以便将数据写在文本文件的一行上,并用comman分隔。然后使用.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()