Парсинг полей из html с помощью lxml

Я пытаюсь разобрать вывод html из вызова URL, но обнаружил, что изо всех сил пытаюсь заставить его работать.

Я использую следующий код:

    import urllib2
    import base64 as b64
    import lxml.html as LH

    request = urllib2.Request('http://%s%s' % (fInput[1], fInput[2]))
    base64string = b64.encodestring('%s:%s' % (fInput[3], fInput[4])).replace('\n', '')
    request.add_header("Authorization", "Basic %s" % base64string)
    response = urllib2.urlopen(request)
    html = response.read()
    root = LH.fromstring(html)
    sibling_content = lambda x: [b.getparent().getnext().text_content() for b in root.cssselect("td b:contains('{0}')".format(x))]
    fields = ['groupList','namelist']


    for result in zip(*[sibling_content(field) for field in fields]):
        print result

Результат, который у меня есть, когда я печатаю вывод:

('Admins', '\nme\nmyself\nirene')('guests', '\nhin\nhinself\nbacon')

Выход, который подходит для того, что мне нужно, имеет такой массив, поэтому я мог бы вставить его в базу данных:

['Admins', 'me','myself','nirene'],['guests', 'hin','hinself','bacon']

После этого я отправляю HTML-код, возвращенный HTTP-запросом:

<BODY bgcolor="#dddddd">
   <TABLE bgcolor="#dddddd" border="1">
      <TR>
         <TD valign="top"><B>MainList</B></TD>
         <TD>
            <TABLE>
               <TR>
                  <TD>
                     <TABLE bgcolor="#dddddd" border="1">
                        <TR>
                           <TD valign="top"><B>groupList</B></TD>
                           <TD>Admins</TD>
                        </TR>
                        <TR>
                           <TD valign="top"><B>namelist</B></TD>
                           <TD>
                              <TABLE>
                                 <TR>
                                    <TD>me</TD>
                                 </TR>
                                 <TR>
                                    <TD>myself</TD>
                                 </TR>
                                 <TR>
                                    <TD>irene</TD>
                                 </TR>
                              </TABLE>
                           </TD>
                        </TR>
                     </TABLE>
                     <TABLE bgcolor="#dddddd" border="1">
                        <TR>
                           <TD valign="top"><B>groupList</B></TD>
                           <TD>guests</TD>
                        </TR>
                        <TR>
                           <TD valign="top"><B>namelist</B></TD>
                           <TD>
                              <TABLE>
                                 <TR>
                                    <TD>hin</TD>
                                 </TR>
                                 <TR>
                                    <TD>hinself</TD>
                                 </TR>
                                 <TR>
                                    <TD>bacon</TD>
                                 </TR>
                              </TABLE>
                           </TD>
                        </TR>
                     </TABLE>
                  </TD>
               </TR>
            </TABLE>
         </TD>
      </TR>
   </TABLE>
</BODY>

Любые идеи о том, как я могу заставить это работать?

Заранее спасибо.


person thclpr    schedule 10.01.2013    source источник
comment
Элементы hin, hinself, bacon в вашем ожидаемом выводе нигде не найдены в вашем HTML.   -  person Bryan    schedule 10.01.2013
comment
Редактирую его, чтобы добавить, моя ошибка при копировании/вставке   -  person thclpr    schedule 10.01.2013


Ответы (3)


Использование xpath:

root=LH.fromstring(html)
[t.xpath('.//td[not(contains(.,"\n"))]/text()')
    for t in root.xpath('.//table[@bgcolor="#dddddd"]')]

вышел:

[['Admins', 'me', 'myself', 'irene'], ['guests', 'hin', 'hinself', 'bacon']]
person root    schedule 10.01.2013
comment
@Thales -- :) если вам часто нужно извлекать данные из html/xml, xpath - действительно хороший инструмент. - person root; 10.01.2013

Я немного смущен вашим вопросом. Вы просто спрашиваете, как повернуть

('Members', '\nme\nmyself\nirene')('Members_2', '\nhin\nhinself\nbacon')

в

['Members', 'me','myself','nirene'],['Members_2', 'hin','hinself','bacon']

Это просто:

>>> x = [('Members', '\nme\nmyself\nirene'), ('Members_2', '\nhin\nhinself\nbacon')]
>>> [[y[0]] + y[1].splitlines()[1:] for y in x]

К вашему сведению, вам следует взглянуть на модуль Python requests. Вместо всего urllib2 хлама с дайджестами он позволяет вам просто написать

requests.get(url, auth=(user, pass))
person Katriel    schedule 10.01.2013
comment
Привет, я правильно обновлю вопрос, но я ищу преобразование вывода в массив. Так что я мог бы использовать данные для вставки в БД - person thclpr; 10.01.2013
comment
и в каком смысле это не отвечает на ваш вопрос - person Katriel; 10.01.2013
comment
Я пошла за кофе :) Хорошо, не могли бы вы привести пример, как я могу применить это в скрипте? я сделал: x =package (переходит на новую строку) print [[y[0]] + y[1].splitlines()[1:] для y в x] и вывод был -1 [['\n' ]] [['\n']] - person thclpr; 10.01.2013
comment
@Thales попробуй разобраться =) Ты уже построил zip(*[sibling_content(field) for field in fields]). Назовите это x. Затем print x и посмотрите, что это такое. - person Katriel; 10.01.2013
comment
Я голосую за ваш ответ. здесь нельзя допускать лени. - person thclpr; 10.01.2013

Я думаю, что просто удаление пробелов из текстового содержимого должно работать. Таким образом, в вашем коде вы можете добавить вызов полосы в эту строку:

sibling_content = lambda x: [b.getparent().getnext().text_content().strip() для b в root.cssselect("td b:contains('{0}')" .формат(х))]

person Oin    schedule 10.01.2013