Python 解析网页中的sre.findall()

Python 解析网页中的sre.findall(),python,parsing,findall,Python,Parsing,Findall,我在Python中使用urllib2和sre解析来自aprs.fi的数据,这样我就可以在我正在编写的一些实时高空气球代码中使用天气数据。解析代码非常简单: import urllib2 import sre APRStracking = urllib2.urlopen( "http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=xml" ) APRSxml =

我在Python中使用urllib2和sre解析来自aprs.fi的数据,这样我就可以在我正在编写的一些实时高空气球代码中使用天气数据。解析代码非常简单:

import urllib2
import sre

APRStracking = urllib2.urlopen( "http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=xml" )

APRSxml = APRStracking.read()

latitude = sre.findall( '<la.*>(.*)</la.*>', APRSxml )
print latitude
导入urllib2
进口sre
APRStracking=urllib2.urlopen(“http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=xml" )
APRSxml=APRStracking.read()
纬度=sre.findall('(.*),APRSxml)
打印纬度
我试图解析的数据是一个XML,如下所示:

<xml>
   <command>get</command>
   <result>ok</result>
   <what>loc</what>
   <found>1</found>
   <entries>
      <entry>
         <name>KD8REX</name>
         <type>l</type>
         <time>1339339410</time>
         <lasttime>1339339410</lasttime>
         <lat>41.95550</lat>
         <lng>-83.65567</lng>
         <altitude>2204.62</altitude>
         <course>15</course>
         <speed>15</speed>
         <symbol>/O</symbol>
         <srccall>KD8REX</srccall>
         <dstcall>APT311</dstcall>
         <status>UofM H.A.S. - Go Blue!</status>
         <status_lasttime>1339339600</status_lasttime>
         <path>WIDE1-1,WIDE3-3,qAR,W8SGZ</path>
      </entry>
   </entries>
</xml>

得到
好啊
loc
1.
KD8REX
L
1339339410
1339339410
41.95550
-83.65567
2204.62
15
15
/O
KD8REX
APT311
UofM H.A.S.-变蓝!
1339339600
宽1-1,宽3-3,qAR,W8SGZ

我对Python不是很熟悉,但我对ser.findall()的理解是,它通过APRSxml查找与正则表达式匹配的任何字符串,然后在列表“latitude”的括号之间追加任何内容。因此,在本例中,与正则表达式匹配的两个值是“lasttime”和“lat”,当我运行此代码时,它只输出
值,而不是
。坦率地说,这就是我的代码工作所需要的一切,但出于好奇,如果有人能告诉我为什么它没有按预期运行,我将不胜感激。谢谢。

您需要将贪婪的星星更改为懒惰的匹配(*?)


解释为何未报告lasttime值。

请尝试此非贪婪版本:

latitude = re.findall('<la.*?>(.*?)</la.*?', APRSxml)
>>> print latitude
['1339339410', '41.95550']

latitude=re.findall('(.*)查看
form
参数,我注意到您可以指定
form=xml
。我将其更改为
json
,看看,您得到了json

{
  "command":"get",
  "result":"ok",
  "what":"loc",
  "found":1,
  "entries":[
    {
      "name":"KD8REX",
      "type":"l",
      "time":"1339339410",
      "lasttime":"1339339410",
      "lat":"41.95550",
      "lng":"-83.65567",
      "altitude":"2204.62",
      "course":"15",
      "speed":"15",
      "symbol":"\/O",
      "srccall":"KD8REX",
      "dstcall":"APT311",
      "status":"UofM H.A.S. - Go Blue!",
      "status_lasttime":"1339339600",
      "path":"WIDE1-1,WIDE3-3,qAR,W8SGZ"
    }
  ]
}
很容易解析。比XML更容易:

import urllib2, json

url = 'http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=json'
data = json.loads(urllib2.urlopen(url).read())

for entry in data['entries']:
  print 'Latitude:', entry['lat']

使用它非常简单。
数据
只是一个Python字典。

Python包含一个易于使用的XML解析器,非常适合此任务:

>>> import urllib2
>>> from xml.etree.ElementTree import parse
>>> APRStracking = urllib2.urlopen("http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=xml")
>>> tree = parse(APRStracking)
>>> tree.find('entries/entry/lat').text
'41.95550'

它为我产生了预期的输出。另外,为什么你使用
sre
而不是
re
?我实际上刚刚意识到我使用的是一个不推荐使用的模块哈哈……但是不管改成re后我仍然只得到了lat值。你应该检查APRSxml的值是否与你认为的值一致(通过
打印它,可能).正如我所说,当我运行代码
findall
时,返回两个值。我在打印后确认了这两个值。奇怪的是,我将正则表达式更改为“(,*),认为lat不可能匹配它,而上次应该匹配。但是打印纬度仍然给了我这个值。这似乎与我所知道的关于正则表达式的一切都相矛盾。我首先尝试了正则表达式复制/粘贴问题中的数据,得到了与@BrenBarn相同的结果。但是运行代码,包括检索数据实际上给出了ricewhite报告的结果。除非设置了DOTALL标志,否则不应该是这种情况。@BrenBarn:urllib返回的xml不包含换行符。你是对的,原始帖子没有准确说明数据是什么。啊,是的,这成功了,谢谢!解释也很好。啊,这成功了,谢谢!我明白了现在,只要匹配就足够满足我的需要了,但我对Python不太熟悉,我认为学习的一个好方法就是玩弄这门语言。这只是一个我无法理解的小怪癖。如果您正在寻找一个更好的解决方案,用正则表达式解析XML(绝对不推荐)看看对你有什么好处。解决眼前问题的最佳方案。我不能给出足够的+1。
{
  "command":"get",
  "result":"ok",
  "what":"loc",
  "found":1,
  "entries":[
    {
      "name":"KD8REX",
      "type":"l",
      "time":"1339339410",
      "lasttime":"1339339410",
      "lat":"41.95550",
      "lng":"-83.65567",
      "altitude":"2204.62",
      "course":"15",
      "speed":"15",
      "symbol":"\/O",
      "srccall":"KD8REX",
      "dstcall":"APT311",
      "status":"UofM H.A.S. - Go Blue!",
      "status_lasttime":"1339339600",
      "path":"WIDE1-1,WIDE3-3,qAR,W8SGZ"
    }
  ]
}
import urllib2, json

url = 'http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=json'
data = json.loads(urllib2.urlopen(url).read())

for entry in data['entries']:
  print 'Latitude:', entry['lat']
>>> import urllib2
>>> from xml.etree.ElementTree import parse
>>> APRStracking = urllib2.urlopen("http://api.aprs.fi/api/get?name=KD8REX&what=loc&apikey=42457.M4AFa3hdkXG31&format=xml")
>>> tree = parse(APRStracking)
>>> tree.find('entries/entry/lat').text
'41.95550'