Технический форум по робототехнике.
MiBBiM » 08 июл 2010, 17:16
надо на питоне:
1. загрузить html страницу
2. найти все вхождения маски в html:
- Код: Выделить всё • Развернуть
<li duration="*" id="*" singer="*" link="*">
* - строка символов
что можно почитать?
Grem » 08 июл 2010, 17:42
п.2 регэкпами на раз делается. Щас Vooon придет, и всё расскажет
- Код: Выделить всё • Развернуть
надо бы отдельный раздел сделать по программированию на ПК
MiBBiM » 08 июл 2010, 21:40
разобрался с первым, нужно подключать urllib. код примерно такой:
- Код: Выделить всё • Развернуть
import urllib
h = urllib.urlopen('http://google.com/') # нужно указывать протокол
print h.read() # печать html документа
P.S> в последнем нужно найти значения строк, помеченных звездочкой
P.P.S> а ещё в urllib есть функции для замены символов, которые не могу быть употреблены в url-адресе. так что можно делать GET запросы абсолютно не напрягаясь:
- Код: Выделить всё • Развернуть
import urllib
find_string = '123 321 !@#'
query = urllib.quote_plus(find_string)
h = urllib.urlopen('http://google.com/search?q=' + query) # поиск в гугле
print h.read() # вывод результата запроса
Добавлено спустя 1 час 12 минут 10 секунд:нашел как распарсить, использую модуль HTMLParser:
- Код: Выделить всё • Развернуть
from HTMLParser import HTMLParser
class myparser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.count = 0
def handle_starttag(self, tag, attrs):
if tag == 'li' and 'duration' in attrs[0][0] and 'id' in attrs[1][0] and 'singer' in attrs[2][0] and 'link' in attrs[3][0]:
print 'singer: ', attrs[2][1], ', link: ', attrs[3][1], ', id: ', attrs[1][1]
self.count += 1
data = """ сюда загнать html"""
pars = myparser()
pars.feed(data)
print pars.count
т.е. нужно наследоваться от класса HTMLParser и обработать функции handle_starttag, handle_endtag
Добавлено спустя 2 часа 13 минут 37 секунд:парсинг валится на реальной странице =( скорее всего там хтмл не совсем валидный, ибо google.com все-таки парсит.
- Код: Выделить всё • Развернуть
Traceback (most recent call last):
File "/home/mibbim/parser.py", line 76, in <module>
pars.feed(text)
File "/usr/lib/python2.6/HTMLParser.py", line 108, in feed
self.goahead(0)
File "/usr/lib/python2.6/HTMLParser.py", line 148, in goahead
k = self.parse_starttag(i)
File "/usr/lib/python2.6/HTMLParser.py", line 249, in parse_starttag
attrvalue = self.unescape(attrvalue)
File "/usr/lib/python2.6/HTMLParser.py", line 387, in unescape
return re.sub(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));", replaceEntities, s)
File "/usr/lib/python2.6/re.py", line 151, in sub
return _compile(pattern, 0).sub(repl, string, count)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Grem » 08 июл 2010, 21:48
вон он сам с помощью регэкспов парсит, я ж писал вам уже, пользуйтесь ими, лучшего ещё не придумали
MiBBiM » 08 июл 2010, 21:54
хах, да это же шаманство. ну, попробую.
Romikgy » 08 июл 2010, 22:05
MiBBiM » 08 июл 2010, 23:56
не, сложно английские тексты читать, в теме не шаря.
Добавлено спустя 1 час 37 минут 46 секунд:может у парсера крыша от кодировки слетела? последняя строка ошибки:
MiBBiM писал(а):- Код: Выделить всё • Развернуть
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
Grem » 08 июл 2010, 23:59
попробуйте пару других сайтов, может тот, который парсите криво написан.
Vooon » 09 июл 2010, 00:43
А страничка гугла должно быть английская, и заголовки
content-type=text/html; charset=utf-8HTML регэкспами парсить не совсем правильно, работать будет только с одним сайтом и до тех пор пока шаблоны не обновят.
Не знаю как HTMLParser а BeautifulSoup вроде лучше.
Ну для этого случая re всетаки напишу:
- Код: Выделить всё • Развернуть
import re
LI_TAG = re.compile(r'(\<li\ duration="(?P<duration>.*?)"\ id="(?P<id>.*?)"\ singer="(?P<singer>.*?)"\ link="(?P<link>.*?)"\>)', re.UNICODE)
А ошибка связана с конвертом
str() -> unicode() по умолчанию вызывается
unicode_ = str_.decode('ascii')а нужно
unicode_ = str_.decode('utf-8')Добавлено спустя 5 минут 57 секунд:- Код: Выделить всё • Развернуть
>>> import re
>>> LI_TAG = re.compile(r'(\<li\ duration="(?P<duration>.*?)"\ id="(?P<id>.*?)"\ singer="(?P<singer>.*?)"\ link="(?P<link>.*?)"\>)', re.UNICODE)
>>> m= LI_TAG.match('<li duration="abc" id="i213" singer="artist" link="some-link">')
>>> m.groupdict()
{'duration': 'abc', 'singer': 'artist', 'link': 'some-link', 'id': 'i213'}
>>>
MiBBiM » 09 июл 2010, 00:54
Vooon, спасибо огромное =) я к этому времени написал регэксп только для отлова всей строки, без деления на нужную инфу =)
MiBBiM » 09 июл 2010, 22:39
таак, теперь нужно разобраться с POST запросами. для начала ищю простенькую форму "входа".
А глобальная задача - прикинутся браузером и ходить по страничкам
Grem » 10 июл 2010, 00:02
httplib вам в помощь, а вообще почитайте ка хотя бы Саммерфильда.
MiBBiM » 11 июл 2010, 14:47
разобрался с кукисами. осталась последняя проблема - виснет GUI во время сетевых запросов
Grem » 11 июл 2010, 17:57
по поводу гуи ничего не скажу, давно, когда питон изучал, до гуи так и не дошло, ибо не нужен мне был. Поищите, возможно, что он потоко не безопасен.
В jаvа у swing, например, нельзя в потоке обновления гуи делать что либо долговременное, ибо если что-то занимает ЕDT поток, то гуй ждет конца монитора и соотв. не откликается.
MiBBiM » 03 авг 2010, 12:33
в питоне есть какое-нибудь автоматическое определение кодировки? нужно привести в 'utf-8' текст, кодированный 'win1251' или 'utf-8' (это id3 теги).