1 Востаннє редагувалося Q-bart (06.04.2015 15:36:26)

Тема: Парсинг

Вітаю!
Почав я вчити Grab вже кілька днів тому. Для прикладу взяв сторінку активних тем Replace, і хочу вивести всі активні теми.

# -*- coding: utf-8 -*-
import sys
    
from grab import Grab
g = Grab()
url = 'http://replace.org.ua/search/recent'
g.go(url)
c = g.xpath_list("//div[@class='item-subject']/h3[@class='hn']/a")
for i in c:
    print i.text

Тоді видає

UnicodeEncodeError: 'charmap' codec can't encode character u'\u0456' in position
8: character maps to <undefined>

Але якщо просто 'print i', то виходить таке:
http://s7.сайт-злодій/uploads/images/2015/04/e65ee4ebd75ab508a4545d9934b6fd9f.png
Це значить,що скрипт пропарсив сторінку але не може відобразити???
Що робити?

2 Востаннє редагувалося Q-bart (06.04.2015 14:11:27)

Re: Парсинг

Ось що нагуглив..
'charmap' codec can't encode character u'\u0456'  означає, що скрипт зустрів українську букву "і"(u'\u0456), і не може її розпізнати...
Джерело
Там пишуть робити так:
print s.decode("utf-8").encode("cp866", "ignore")
или производите замену
print s.decode("utf-8").replace(u'\u0456', u'i')

Але код

from grab import Grab
g = Grab()
g.go('http://replace.org.ua/search/recent')
c = g.xpath_list("//div[@class='item-subject']/h3[@class='hn']/a")
for i in c:
    print i.decode("utf-8").encode("cp866", "ignore")

Все рівно не працює. І викликає помилку

AttributeError: 'HtmlElement' object has no attribute 'decode'

В чому проблема?

3

Re: Парсинг

застосуйте декод то i.text, а не до i

Подякували: Q-bart1

4

Re: Парсинг

Master_Sergius написав:

застосуйте декод то i.text, а не до i

Так?

from grab import Grab
g = Grab()
g.go('http://replace.org.ua/search/recent')
c = g.xpath_list("//div[@class='item-subject']/h3[@class='hn']/a")
for i in c:
    print i.text.decode("utf-8").encode("cp866", "ignore")

То тепер викликає помилку

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-6: ordin
al not in range(128)

5 Востаннє редагувалося Master_Sergius (06.04.2015 15:06:21)

Re: Парсинг

Щоб Ви зрозуміли різницю між decode i encode:

>>> a = 'абв'
>>> a
'\xd0\xb0\xd0\xb1\xd0\xb2'
>>> a.decode('utf-8')
u'\u0430\u0431\u0432'
>>> a.encode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)
>>> a.decode('utf-8').encode('cp1251')
'\xe0\xe1\xe2'
>>> a.encode('cp1251')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/cp1251.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_table)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 0: ordinal not in range(128)

Коротше кажучи, спочатку спробуйте надрукувати теги лише з decode('utf-8') i encode('utf-8'), а тоді можна буде рухатися далі

п.с. рекомендую статтю:

Прихований текст

російською мовою, тому заховав у спойлер - http://habrahabr.ru/post/135913/

Подякували: Q-bart1

6

Re: Парсинг

ВЕЛЕЧЕЗНЕ Дякую!!
Нарешті я зрозумів як то робиться, те кодування... А то вже три дні мучився думаючи, що якась помилка при парсері. А насправді через "і"
Отже, якщо в когось буде теж така помилка, викладаю код

from grab import Grab
g = Grab()
g.go('http://replace.org.ua/search/recent')
c = g.xpath_list("//div[@class='item-subject']/h3[@class='hn']/a")
for i in c:
    print i.text.encode('utf-8').decode('UTF-8').replace(u'\u0456', u'i')
Подякували: syprox1

7 Востаннє редагувалося Q-bart (06.04.2015 15:34:04)

Re: Парсинг

Але чи не могли б ви мені допомогти ще.
Можете сказати як називаються оті елементи... <Element a at 0x2746c90> Хочу розібратися що то таке, почитати щось про них...
P.S статтю прочитаю...

8

Re: Парсинг

Вам також потрібно тоді почитати про DOM (Doument Object Model), по суті елементи - це є елементи цієї моделі.

Подякували: Q-bart1

9

Re: Парсинг

А з "є" "ї" "ґ", апострофом проблем немає?

10

Re: Парсинг

Sensetivity написав:

А з "є" "ї" "ґ", апострофом проблем немає?

Якщо кодування — cp866 (DOS-кирилиця в російських та українських локалях вінди), проблема буде з Ґґ, Іі та «типографічним апострофом» (’), тоді як Єє, Її та «програмістський апостроф» (') підтримуються.

11 Востаннє редагувалося Q-bart (17.04.2015 17:17:42)

Re: Парсинг

Вітаю!
Знову повернувся до Grab, хоча вже почав вчити нове, проте...
Намагаючись пропарсити(вибрали 1 елемент) одну сторінку таким кодом

print g.doc.select("//div[@class='user-name']/div")

Отримую наступне:

<selection.selector_list.SelectorList object at 0x02571C38>

Якщо пробувати видрукувати за допом. .text, то виходить таке:

<bound method SelectorList.text of <selection.selector_list.SelectorList object
at 0x02520C38>>

Що то таке? Як мені дістати норм. текст?

12

Re: Парсинг

Як щодо знайти документацію, а не вгадувати методи і поля?

SelectorList виглядає як список, тому спробуйте витягнути елементи з нього і до них уже застосовувати .text.

13

Re: Парсинг

Я сам бачив що там пише 'list', і тому пробував

print g.doc.select("//div[@class='user-name']/div").[0]

Та виходила помилка

IndexError: list index out of range

В документації шукав, нічого не знайшов, якщо можливо то дайте посилання..

14

Re: Парсинг

Q-bart написав:

Я сам бачив що там пише 'list', і тому пробував

print g.doc.select("//div[@class='user-name']/div").[0]

Та виходила помилка

IndexError: list index out of range

В документації шукав, нічого не знайшов, якщо можливо то дайте посилання..

Так не знайшло нічого з таким селектором, ні? Протестуйте з селектором, який точно є на сторінці.

15 Востаннє редагувалося Q-bart (17.04.2015 18:40:59)

Re: Парсинг

Я перше авторизуюсь на пошті, тисну submit, і тоді хочу парсити..

g.doc.set_input("Login","*****")
g.doc.set_input("Password","***")
g.doc.submit()

Тому, можливо, через те що не пройшла авторизація не хоче нічого знайти???

16

Re: Парсинг

Результат

print g.doc.select('//a').text()

в студію.

17

Re: Парсинг

Не виводить нічого...

18

Re: Парсинг

Я попробував ввести в поле пошуку гугла запит

from grab import Grab
g = Grab()
g.go('https://www.google.com.ua/')
g.doc.set_input("q","grab")
g.doc.submit()
print g.doc.select('//head/title').text()

print g.doc.select('//h3[@class="r"]/a')

Виводить:

Grab - python фреймворк для парсинга сайтов
<selection.selector_list.SelectorList object at 0x022F9E90>

Перше мало б вивести: "grab - Пошук Google", чи не так? А виводить те що має вивести друге???

Чи grab бачить сторінку не так як я її в браузері, натиснувши "Переглянути елемент"
Що то таке???

19

Re: Парсинг

Знайшов проблему, вірніше підказали на stackoverflow, вся проблема була в g.doc.submit(), треба було вказувати submit_name

g.doc.submit(submit_name = 'btnK')

20

Re: Парсинг

Hello