2013-11-12 4 views
1

Выход "curl -s http://122.160.230.125:8080/gbod/gb_on_demand.do | head -115 | tail -3" дает следующееExtract конкретные числовые данные из локонов выхода

<li>Balance quota:&nbsp;&nbsp;&nbsp;78.26&nbsp;GB</li> 
<li>High speed data limit:&nbsp;&nbsp;&nbsp;80.0&nbsp;GB</li> 
<li>No. of days left in the current bill cycle:&nbsp;&nbsp;&nbsp;28</li> 

и curl -s http://122.160.230.125:8080/gbod/gb_on_demand.do | head -115 | tail -3 | awk '{gsub (/&nbsp;/, " "); gsub (/\<li>/, ""); gsub (/\<\/li>/, " "); print}' дает

Balance quota: 78.26 GB 
High speed data limit: 80.0 GB 
No. of days left in the current bill cycle: 28 

Как извлечь только числовые данные из каждой строки? Кроме того, есть ли лучший способ извлечь эти данные?

+1

добро пожаловать в StackOverflow.com. Обновите свой профиль, чтобы указать свое имя. Затем имя появится на вашем значке, и вам не нужно включать его в каждый вопрос. Вы также можете получить значок, если вы заполните свой профиль. – Chandranshu

ответ

1

Использование строк и регулярных выражений для анализа HTML очень хаки и очень хрупкие.

Но если вы хотите расширить то, что вы уже делаете, надежность прокляты, все, что вам нужно, это простое регулярное выражение для совпадения чисел:

curl -s http://122.160.230.125:8080/gbod/gb_on_demand.do | 
    head -115 | tail -3 | 
    awk '{gsub (/&nbsp;/, " "); gsub (/\<li>/, ""); gsub (/\<\/li>/, " "); print} | 
    grep -o -E -e '[0-9][0-9.]+' 

(я никогда не могу вспомнить, если я получил флаги имеют право работать во всех вариантах grep. Это определенно работает на BSD grep, если оно не работает на вашем, флаги - -o, чтобы печатать только совпадение, а не всю строку, -E, чтобы использовать расширенные регулярные выражения, а не основные, и конечно -e, чтобы указать рисунок.)

+1

Я думаю, что проблема в вашем регулярном выражении. Он позволяет использовать несколько десятичных точек. Так что 9 ...... также появятся. (Не говоря уже о том, что сама точка является специальным символом и будет соответствовать любому символу) Я думаю, что правильное регулярное выражение будет «[0-9] * \.? [0-9] + ''. – Chandranshu

+1

@Chandranshu: Конечно, но мы говорим о коде как хрупком, как 'head -115 | хвост -3', поэтому я думаю, что мы можем предположить, что он будет выглядеть очень близко к тому, что опубликовал OP, или у него будет намного худшие проблемы. Так что лучше просто держать вещи просто. Между тем, ваше регулярное выражение все еще не правильно - оно не будет обрабатывать '-42' или' 42.' или '1e6' или множество других допустимых номеров. – abarnert

+1

Я принимаю ваш аргумент! :) – Chandranshu

1

Если вы хотите что-то менее хрупкое, чем re лежащий на том, что линии, которые вы хотите, находятся на линиях 113-115, вот какой-то код Python, используя BeautifulSoup, чтобы сделать то же самое более красиво.

Не зная, как выглядит ваш исходный файл, мне пришлось сделать много предположений. В частности, я предполагаю, что вы хотите извлечь числа из каждый<li> тег в файл. Если вы хотите извлекать числа только из тегов <li>, которые имеют номера или только из тегов <li> под определенным тегом <ul> с хорошим атрибутом id или доступны через простой путь от корня или что-то еще, код будет немного другой.

import re 
import urllib.request 
import bs4 

url = 'http://122.160.230.125:8080/gbod/gb_on_demand.do' 
page = urllib.request.urlopen(url).read() 
soup = bs4.beautifulSoup(page) 
for li in soup.find_all('li'): 
    print re.search('\d[\d.]+', li.text).group() 
+0

Пожалуйста, посмотрите мой комментарий о регулярном выражении, используемом в другом ответе. – Chandranshu

1

Один из способов сделать это:

curl -s http://122.160.230.125:8080/gbod/gb_on_demand.do | awk -F"[;&<]" 'NR>115-3 && NR<=115 {print $8}' 
78.26 
80.0 
28 

PS, если вы после выхода из curl -s http://122.160.230.125:8080/gbod/gb_on_demand.do мы можем наверняка очистить это больше.

1

Предполагая, что ответ является правильным XML, вы можете использовать XMLStarlet, чтобы получить содержимое <li> элементов:

http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.html#d0e270

Вы должны получить вокруг головы, как определить запрос, но imho это того стоит, так как вы могли бы найти полученные знания в будущих запросах xml/html.

Плагины для браузера, которые помогут вам определить селектор css, вам нужно точно выбрать нужные вам элементы (вместо того, чтобы предполагать, что они всегда отображаются в тех же строках). К сожалению, я не могу найти ссылки прямо сейчас.

Оттуда используйте grep или sed или awk, как и другие рекомендации.

0

Как и было предложено, я попробовал следующее, и я получил то, что искал.

import urllib2 
import re 
from bs4 import BeautifulSoup 
url = 'http://122.160.230.125:8080/gbod/gb_on_demand.do' 
page = urllib2.urlopen(url).read() 
soup = BeautifulSoup(page) 
data = [] 
for li in soup.find_all('li', limit=4): 
     somevar = re.search('\d[\d.]+', li.text).group(); 
     data.append(somevar) 

print "DSL Number: ", data[0] 
print "Balance: ", data[1], "GB" 
print "Limit: ", data[2], "GB" 
print "Days Left: ", data[3] 

Использование этого сценария python имеет больше смысла, чем использование curl для моего проекта.

Спасибо всем за помощь.

Смежные вопросы