Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 16, 2013 06:19:14

roloyar
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

Всем здрасьте! Я в питоне новичок, так что не судите строго. За советы заранее спасибо!

Цель - построить простой скрейпер. Конкретнее, имеется задача - используя mechanize зайти на украиноязычный сайт (сайт Верховной Рады, но думаю детали тут не так важны), используя BeautifulSoup вытащить из таблицы текст (только из одного столбца), немного его обработать (убрать HTML тэги и т.п.) и записать его с помощью модуля csv в файл.

Вот мой код:

from BeautifulSoup import BeautifulSoup
from mechanize import Browser
import csv
url = 'http://w1.c1.rada.gov.ua/pls/zweb2/webproc4_1?pf3511=48671'
br = Browser()
br.open(url)
soup = BeautifulSoup(br.response())
div = soup.find('div', attrs={'class':'zp-info'})
content = div.findAll('dd')
output = []
for d in content:
    output.append(d.text.strip().split(','))
outfile = open('test_out.txt', 'w')
writer = csv.writer(outfile)
writer.writerows(output)

В результате получаю ошибку:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 5-7: ordinal not in range(128)
Если просто сделать
print output
вылезает, как я понимаю, список с юникод-символами вместо букв.

Перепробовал уже много всего. Ближе всего к цели пришел сделав следующее:
proper = repr(output).decode('raw_unicode_escape')
print proper
Но тут проблема в том, что это получается не список (что мне нужно для модуля csv) а unicode-объект.

Короче записать в текстовый файл кириллицу еще кое-как получается, если без csv напрямую, но достичь изначальной цели так и не выходит.

Очень еще раз заранее спасибо за любые советы и помощь!

Офлайн

#2 Окт. 16, 2013 12:04:57

sanodin
От:
Зарегистрирован: 2011-06-16
Сообщения: 515
Репутация: +  31  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

# coding: cp1251
import csv
rows=[[u'\xca\xe0\xe1\xb3\xed\xe5\xf2 '], [u'3 \xf1\xe5\xf1\xb3\xff VII \xf1\xea\xeb\xe8\xea\xe0\xed\xed\xff']]
outfile = open('test_out.txt', 'w')
writer = csv.writer(outfile)
for i in rows:
    result = ''.join(i)
    print result.encode('ISO 8859-1')
    writer.writerows(result.encode('ISO 8859-1'))
s = u'\xf1'
print s.encode('ISO 8859-1')
rows==output

Отредактировано sanodin (Окт. 16, 2013 12:07:27)

Офлайн

#3 Окт. 16, 2013 17:12:51

roloyar
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

sanodin
# coding: cp1251
import csv
rows=[[u'\xca\xe0\xe1\xb3\xed\xe5\xf2 '], [u'3 \xf1\xe5\xf1\xb3\xff VII \xf1\xea\xeb\xe8\xea\xe0\xed\xed\xff']]
outfile = open('test_out.txt', 'w')
writer = csv.writer(outfile)
for i in rows:
    result = ''.join(i)
    print result.encode('ISO 8859-1')
    writer.writerows(result.encode('ISO 8859-1'))
s = u'\xf1'
print s.encode('ISO 8859-1')
rows==output
Sanodin, большое спасибо! Но, к сожалению, проблему не решило.

Дело в том, что на выходе если сделать
print output
то я получаю
[[u'3424 \u0432\u0456\u0434 14.10.2013'], [u'3 \u0441\u0435\u0441\u0456\u044f VII \u0441\u043a\u043b\u0438\u043a\u0430\u043d\u043d\u044f'],...
и так далее, весь список содержит, если я правильно понимаю, символы кириллицы закодированные в юникоде (я еще только пытаюсь со всеми этими кодировками разобраться). То есть исходник у меня не в cp1251. Следовательно ничего с ним потом по инструкции sanodin не получается.

Если я попытаюсь сделать
print output.encode('ISO 8859-1')
то получаю
AttributeError: 'list' object has no attribute 'encode'
Это, впрочем, вполне ожидаемо, так как это список. Но даже если взять один элемент из этого списка и попытаться сделать xxx.encode('ISO 8859-1') то выходит то же самое, что выше в
print output
короче символы вообще не меняются.

Я практически уверен, что все ломается на стадии for при записи значений в список:
for d in content:
	output.append(d.text.strip().split(','))
Если просто записывать, без .text.strip().split(',')) все остается в той кодировке, в которой было (но с разметкой которая мне не нужна), если я пытаюсь используя .text.strip().split(',')) избавиться от HTML разметки, на выходе получаю кашу…

И еще, sanodin, если запустить твой скрипт, то он запишет в test_out.txt все символы из result по одному символу на строке. Несмотря даже на то, что
type(result)
возвращает
<type 'list'>
Я сам не понимаю, почему, но говорю просто раз заметил…

Эх, надеюсь я с этим таки разберусь.

Отредактировано roloyar (Окт. 16, 2013 17:29:39)

Офлайн

#4 Окт. 16, 2013 17:47:29

sanodin
От:
Зарегистрирован: 2011-06-16
Сообщения: 515
Репутация: +  31  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

Все работает…не понимаю, объясните что нужно

from BeautifulSoup import BeautifulSoup
from mechanize import Browser
import csv
url = 'http://w1.c1.rada.gov.ua/pls/zweb2/webproc4_1?pf3511=48671'
br = Browser()
br.open(url)
soup = BeautifulSoup(br.response())
div = soup.find('div', attrs={'class':'zp-info'})
content = div.findAll('dd')
output = []
for d in content:
    output.append(d.text.strip().split(','))
outfile = open('test_out.txt', 'w')
writer = csv.writer(outfile)
for i in output:
    result = ''.join(i)
    print result.encode('ISO 8859-1')
    writer.writerows(result.encode('ISO 8859-1'))
единственное, записывает в файл по одному символу в строке, ну это Вы и сами переделаете

Отредактировано sanodin (Окт. 16, 2013 18:03:16)

Офлайн

#5 Окт. 16, 2013 17:50:32

bismigalis
Зарегистрирован: 2010-10-02
Сообщения: 449
Репутация: +  47  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

csv модуль из python2 напрямую не работает с unicode, поэтому ему надо отдавать закодированную информацию

Офлайн

#6 Окт. 16, 2013 18:10:34

roloyar
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

sanodin
Все работает…не понимаю, объясните что нужно
from BeautifulSoup import BeautifulSoup
from mechanize import Browser
import csv
url = 'http://w1.c1.rada.gov.ua/pls/zweb2/webproc4_1?pf3511=48671'
br = Browser()
br.open(url)
soup = BeautifulSoup(br.response())
div = soup.find('div', attrs={'class':'zp-info'})
content = div.findAll('dd')
output =
for d in content:
output.append(d.text.strip().split(','))
outfile = open('test_out.txt', ‘w’)
writer = csv.writer(outfile)
for i in output:
result = ‘'.join(i)
print result.encode(’ISO 8859-1')
writer.writerows(result.encode('ISO 8859-1'))
единственное, записывает в файл по одному символу в строке, ну это Вы и сами переделаете
У меня если запустить скрипт в чистом виде (как у вас) то выдает ошибку:
UnicodeEncodeError: ‘latin-1’ codec can't encode characters in position 5-7: ordinal not in range(256)

Офлайн

#7 Окт. 16, 2013 18:11:11

roloyar
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

bismigalis
csv модуль из python2 напрямую не работает с unicode, поэтому ему надо отдавать закодированную информацию
Закодированную в каком виде?

Офлайн

#8 Окт. 16, 2013 18:28:30

sanodin
От:
Зарегистрирован: 2011-06-16
Сообщения: 515
Репутация: +  31  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

а просто в cp1251 ?
это

u'3424 \u0432\u0456\u0434 14.10.2013'

u=u'3424 \u0432\u0456\u0434 14.10.2013'
print u.encode('cp1251')

Отредактировано sanodin (Окт. 16, 2013 18:30:59)

Офлайн

#9 Окт. 16, 2013 18:36:00

roloyar
Зарегистрирован: 2013-10-16
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

sanodin
а просто в cp1251 ?
это
u'3424 \u0432\u0456\u0434 14.10.2013'

u=u'3424 \u0432\u0456\u0434 14.10.2013'
print u.encode('cp1251')

Так все получается. даже если просто сделать print u. Я думаю проблема в том, что у все это с списке. А список так и отображается - списком со значками, а не читабельным текстом. и csv его не воспринимает.

Офлайн

#10 Окт. 16, 2013 18:48:41

sanodin
От:
Зарегистрирован: 2011-06-16
Сообщения: 515
Репутация: +  31  -
Профиль   Отправить e-mail  

Проблема с кодировкой кириллицы - BeautifulSoup и csv

у вас список списков, переделать в строку и все
а в моем коде вы так делали ?

.encode('cp1251')
.decode('cp1251')
кодировками пробуйте подобрать

Отредактировано sanodin (Окт. 16, 2013 19:00:23)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version