为我格式错误的帖子和书面代码道歉,第一篇文章!我确定这是一个简单的修复,但似乎无法弄明白。
问题1:我正在为Eve Online API编写XML scraper。我需要使用type id="X"
迭代其中包含空格(*BeautifulSoup*
)的HTML标记。我想迭代XML中的项ID标记(本例中为2)。我不确定*Data.iter*
是否是正确的做法。我知道打印Data.buy会在XML中找到第一个购买标签并打印子项,但找不到相同的方法来打印第一个数据。'type id="x"'
。
问题2:欢迎任何关于如何继续刮擦过程的方向。我正考虑将买/卖/全部导出到某种存储(正在考虑CSV文件但不是正面),不同的商品ID和买/卖订单存储不同。
import requests #Used to service API connection
from lxml import html #Used to parse XML
from bs4 import BeautifulSoup #Used to read XML table on webpage
ItemTypeID1 = 34
ItemTypeID2 = 35
RegionID = 10000002
Webpage = requests.get('http://api.eve-central.com/api/marketstat?typeid=%i&typeid=%i®ionlimit=%i' % (ItemTypeID1, ItemTypeID2, RegionID))
#Check if page is up
if Webpage.status_code == 200:
#Convert webpage to %Data
Data = BeautifulSoup(Webpage.text, 'lxml')
#Problem line
for item in Data.iter('type id='):
print 'something'
http://api.eve-central.com/api/marketstat?typeid=34&typeid=35®ionlimit=10000002
<?xml version='1.0' encoding='utf-8'?>
<evec_api version="2.0" method="marketstat_xml">
<marketstat><type id="34">
<buy><volume>21648183554</volume><avg>5.34</avg><max>5.78</max><min>2.00</min><stddev>0.83</stddev><median>5.52</median><percentile>5.58</percentile></buy>
<sell><volume>15987043271</volume><avg>6.20</avg><max>15.00</max><min>5.58</min><stddev>1.38</stddev><median>6.00</median><percentile>5.85</percentile></sell>
<all><volume>37635226825</volume><avg>5.71</avg><max>15.00</max><min>2.00</min><stddev>1.40</stddev><median>5.54</median><percentile>4.16</percentile></all>
</type><type id="35">
<buy><volume>4163954948</volume><avg>7.26</avg><max>9.39</max><min>4.02</min><stddev>1.60</stddev><median>6.48</median><percentile>9.24</percentile></buy>
<sell><volume>10154431073</volume><avg>11.84</avg><max>17.41</max><min>9.00</min><stddev>1.80</stddev><median>10.59</median><percentile>9.46</percentile></sell>
<all><volume>14318386021</volume><avg>10.51</avg><max>17.41</max><min>4.02</min><stddev>2.21</stddev><median>10.00</median><percentile>5.87</percentile></all>
</type></marketstat>
</evec_api>
答案 0 :(得分:1)
type id=
不是标记。元素的标记名称为type
,id
是该元素的属性。
for item in Data.find_all('type'):
print item.get('id')
对于您引用的URL,此代码将输出:
34 35
代码只是找到标记名为“type”的所有元素,并显示找到的每个标记的id
属性。
您可以访问嵌套的buy
和sell
代码中包含的数据:
for item in Data.find_all('type'):
print item.get('id')
volume = item.buy.volume.text
avg = item.buy.volume.text
# etc.
显示了如何获取每个项目的volume和avg标记中包含的数据。
还有一个可用的JSON API,可能更容易使用,尤其是在使用requests
模块时:
import requests
url = 'http://api.eve-central.com/api/marketstat/json' # the JSON endpoint
params = {'typeid': (34, 35), 'RegionID': 10000002}
r = requests.get(url, params=params)
data = r.json()
这为您提供了一个可以使用的Python词典列表:
for type_ in data:
print '{}: volume = {}, avg = {}'.format(type_['buy']['forQuery']['types'][0], type_['buy']['volume'], type_['buy']['avg'])
34: volume = 110242267166, avg = 4.29419161677 35: volume = 40908217125, avg = 6.71507628294
虽然从XML中获取类型id,但与XML相比有点尴尬。
答案 1 :(得分:0)
你有几个问题,你似乎混淆了 bs4 和 lxml 语法, iter 是一个lxml方法, type 是节点, id 是节点的属性。
由于您使用的是lxml,只需忘记bs4并获取数据非常简单:
from lxml import html # Used to parse XML
ItemTypeID1 = 34
ItemTypeID2 = 35
RegionID = 10000002
webpage = requests.get('http://api.eve-central.com/api/marketstat?typeid=%i&typeid=%i®ionlimit=%i' % (
ItemTypeID1, ItemTypeID2, RegionID))
if webpage.status_code == 200:
data = html.fromstring(webpage.content)
for item in data.iter('type'):
print(item.get("id")) # print node attribute id value.
buy_dict = {node.tag: node.text for node in item.xpath("buy/*")}
sell_dict = {node.tag: node.text for node in item.xpath("sell/*")}
print(buy_dict)
print(sell_dict)
那会给你:
34
{'min': '2.00', 'max': '5.81', 'median': '5.54', 'volume': '22518685011', 'percentile': '5.72', 'stddev': '0.80', 'avg': '5.37'}
{'min': '5.57', 'max': '15.00', 'median': '6.00', 'volume': '14953114542', 'percentile': '5.78', 'stddev': '1.38', 'avg': '6.21'}
35
{'min': '4.02', 'max': '9.20', 'median': '6.65', 'volume': '4170891614', 'percentile': '9.20', 'stddev': '1.59', 'avg': '7.25'}
{'min': '8.90', 'max': '17.41', 'median': '10.59', 'volume': '10089810619', 'percentile': '9.44', 'stddev': '1.84', 'avg': '11.83'}
然后写入csv:
import requests # Used to service API connection
from lxml import html # Used to parse XML
from csv import DictWriter
ItemTypeID1 = 34
ItemTypeID2 = 35
RegionID = 10000002
webpage = requests.get('http://api.eve-central.com/api/marketstat?typeid=%i&typeid=%i®ionlimit=%i' % (
ItemTypeID1, ItemTypeID2, RegionID))
if webpage.status_code == 200:
with open("data.csv", "w") as f:
wr = DictWriter(f, fieldnames=["buy/sell", 'volume', 'min', 'max', 'median', 'percentile', 'stddev', 'avg'])
wr.writeheader()
data = html.fromstring(webpage.content)
for item in data.iter('type'):
buy_dict = {node.tag: node.text for node in item.xpath("buy/*")}
buy_dict["buy/sell"] = "buy"
sell_dict = {node.tag: node.text for node in item.xpath("sell/*")}
sell_dict["buy/sell"] = "sell"
wr.writerows([buy_dict, sell_dict])
哪个会给你:
buy/sell,volume,min,max,median,percentile,stddev,avg
buy,22518685011,2.00,5.81,5.54,5.72,0.80,5.37
sell,14953114542,5.57,15.00,6.00,5.78,1.38,6.21
buy,4170891614,4.02,9.20,6.65,9.20,1.59,7.25
sell,10089810619,8.90,17.41,10.59,9.44,1.84,11.83