Проблема с Python CSV, помещающим каждую букву в новое поле

Я пытаюсь поместить список URL-адресов в CSV-файл, который я очищаю с веб-страницы, используя urllib2 и BeautifulSoup. Я пробовал писать ссылки на CSV-файл как Unicode, а также конвертировать в utf-8. В обоих случаях каждая буква вставляется в новое поле.

Вот мой код (я пробовал по крайней мере двумя способами):

f = open('filename','wb')
w = csv.writer(f,delimiter=',')
for link in links:
    w.writerow(link['href'])

А также:

f = open('filename','wb')
w = csv.writer(f,delimiter=',')
for link in links:
    w.writerow(link['href'].encode('utf-8'))

links — это список, который выглядит так:

[<a href="#Flyout1" accesskey="2" class="quicklinks" tabindex="1" title="Skip to content">Quick Links: Skip to main page content</a>, <a href="#search" class="quicklinks" tabindex="1" title="Skip to search">Skip to Search</a>, <a href="#News" class="quicklinks" tabindex="1" title="Skip to Section table of contents">Skip to Section Content Menu</a>, <a href="#footer" class="quicklinks" tabindex="1" title="Skip to site options">Skip to Common Links</a>, <a href="http://www.hhs.gov"><img src="/ucm/groups/fdagov-public/@system/documents/system/img_fdagov_hhs_gov.png" alt="www.hhs.gov link" style="width:112px; height:18px;" border="0" /></a>]

Не все ссылки имеют ключ 'href', но я проверяю его в коде, который здесь не показан. В обоих случаях в csv-файл записываются правильные строки, но каждая буква находится в новом поле.

Какие-нибудь мысли?


person tchaymore    schedule 01.07.2011    source источник


Ответы (3)


Из документов: "Строка должна быть последовательностью строк или чисел. ..." Вы передаете одну строку, а не последовательность строк, поэтому каждая буква рассматривается как элемент. Поместите свою строку в список.

Поэтому измените w.writerow(link['href']) на w.writerow([link['href']]).

Примечание. CSV-файл с одним столбцом выглядит точно так же, как обычный текстовый файл. Возможно, вам не нужен csv.

person Steven Rumbalski    schedule 01.07.2011
comment
Rumbalski Спасибо за быструю помощь. Я пришел из PHP, поэтому списки, словари и кортежи Python все еще вызывают у меня затруднения. Я последовал вашему совету и получил эту ошибку: TypeError: string indices must be integers - person tchaymore; 02.07.2011
comment
@tchaymore, эта ошибка связана с 'href', который вы используете для индексации строки. Вы не можете этого сделать. Вы можете использовать целое число для ссылки на место в строке. Но не струна. Я не думаю, что ваша переменная ссылок — это не то, на что вы надеялись (словарь атрибутов в теге <a>). - person Ian C.; 02.07.2011
comment
О господи, глупый я, я по глупости дважды использовал одно и то же имя переменной в сценарии, и одно было строкой, а другое - списком. Спасибо за терпение, которое помогло мне осознать мою глупость. - person tchaymore; 02.07.2011

Я думаю, что под «каждой буквой, вставленной в новое поле», вы имеете в виду что-то вроде этого, верно?

h,t,t,p,:,/,/,w,w,w,.,g,o,o,g,l,e,.,c,o,m

Если это так, то writerow() перебирает символы в вашей строке и интерпретирует их как отдельные столбцы. Попробуйте вместо этого использовать writerow([link['href']]).

Редактировать: Похоже, @Steven Rumbalski опередил меня в этом!

person Greg Haskins    schedule 01.07.2011

Согласно документам, writerow() берет итерируемый объект и, проходя по нему, выводит CSV-представление этого. Ваша проблема в том, что строка является итерируемым объектом. Если у меня есть:

mystring = 'foo'

Python позволит мне перебирать вот так:

for c in mystring:
    print c

И я получу:

f
o
o

Это удобная функция, но в данном случае она работает против вас.

Вы не хотите, чтобы writerow() перебирал строку, вы хотите, чтобы он перебирал список строк, разделяя строки запятыми, а не символами. В этом случае вы захотите составить список из таких строк:

w.writerow([link['href']])
person Ian C.    schedule 01.07.2011