механизировать отправку формы проблема кодировки символов - PullRequest
6 голосов
/ 07 июля 2011

Я пытаюсь очистить http://www.nscb.gov.ph/ggi/database.asp, конкретно все таблицы, которые вы получаете при выборе муниципалитетов / провинций.Я использую Python с lxml.html и механизировать.мой скребок до сих пор работает нормально, однако я получаю HTTP Error 500: Internal Server Error при представлении муниципалитета [19] "Пеньяррубия, Абра".Я подозреваю, что это связано с кодировкой символов.Я предполагаю, что символ ены (n с тильдой выше) вызывает эту проблему.Как я могу это исправить?

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

from BeautifulSoup import BeautifulSoup
import mechanize
import lxml.html
import csv



class PrettifyHandler(mechanize.BaseHandler):
    def http_response(self, request, response):
        if not hasattr(response, "seek"):
            response = mechanize.response_seek_wrapper(response)
        # only use BeautifulSoup if response is html
        if response.info().dict.has_key('content-type') and ('html' in response.info().dict['content-type']):
            soup = BeautifulSoup(response.get_data())
            response.set_data(soup.prettify())
        return response

site = "http://www.nscb.gov.ph/ggi/database.asp"

output_mun = csv.writer(open(r'output-municipalities.csv','wb'))
output_prov = csv.writer(open(r'output-provinces.csv','wb'))

br = mechanize.Browser()
br.add_handler(PrettifyHandler())


# gets municipality stats
response = br.open(site)
br.select_form(name="form2")
muns = br.find_control("strMunicipality2", type="select").items
# municipality #19 is not working, those before do
for pos, item in enumerate(muns[19:]): 
    br.select_form(name="form2")
    br["strMunicipality2"] = [item.name]
    print pos, item.name 
    response = br.submit(id="button2", type="submit")
    html = response.read()
    root = lxml.html.fromstring(html)
    table = root.xpath('//table')[1]
    data = [
               [td.text_content().strip() for td in row.findall("td")] 
               for row in table.findall("tr")
           ]
    print data, "\n"
    for row in data[2:]:
        if row: 
            row.append(item.name)
            output_mun.writerow([s.encode('utf8') if type(s) is unicode else s for s in row])
    response = br.open(site) #go back button not working

# provinces follow here

Большое спасибо!

редактировать:в частности, ошибка возникает в этой строке

response = br.submit(id="button2", type="submit")

Ответы [ 2 ]

1 голос
/ 18 июля 2011

Хорошо, нашел это.Это красивый суп, который конвертируется в unicode и prettify возвращает utf-8 по умолчанию.Вы должны использовать:

response.set_data(soup.prettify(encoding='latin-1'))
1 голос
/ 15 июля 2011

быстрый и грязный хак:

def _pairs(self):
    return [(k, v.decode('utf-8').encode('latin-1')) for (i, k, v, c_i) in self._pairs_and_controls()]

from mechanize import HTMLForm
HTMLForm._pairs = _pairs

или что-то менее инвазивное (я думаю, что нет других решений, потому что класс Item защищает поле 'name')

item.__dict__['name'] = item.name.decode('utf-8').encode('latin-1')

до

br["strMunicipality2"] = [item.name]
...