Создание кадра данных Pandas из вложенных неупорядоченных HTML-списков - PullRequest
0 голосов
/ 07 мая 2018

У меня есть веб-страница неупорядоченных списков, и я хочу превратить их в кадр данных pandas в качестве первого шага рабочего процесса НЛП.

import pandas as pd
from bs4 import BeautifulSoup
html = '''<html>
        <body>
          <ul>
              <li>
              Name
                    <ul>
                        <li>Many</li>
                        <li>Stories</li>
                    </ul>
                </li> 
          </ul>
          <ul>
              <li>
              More
              </li>
         </ul>
         <ul>
             <li>Stuff 
                     <ul>
                         <li>About</li>
                    </ul>
            </li>
        </ul>
        </body>
        </html>'''

 soup = BeautifulSoup(html, 'lxml')

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

   0    1     2
0 Name  Many  Stories
1 More  null  null
2 Stuff About null

Я пытался использовать следующий код, чтобы получить все элементы списка (вместе с подсписками)

target = soup.find_all('ul')

Но он возвращает двойные результаты:

[<li>
                   Name
                         <ul>
 <li>Many</li>
 <li>Stories</li>
 </ul>
 </li>, <li>Many</li>, <li>Stories</li>, <li>
                   More
                   </li>, <li>Stuff 
                          <ul>
 <li>About</li>
 </ul>
 </li>, <li>About</li>]

Действительно потерянный здесь. Благодарю.

1 Ответ

0 голосов
/ 11 мая 2018

Разбивка в комментариях, наслаждайтесь!

from lxml import etree
import re

#Convert html string to correct format for parsing with XPATHs
root = etree.XML(html)
tree = etree.ElementTree(root)

#Your XPATH Selector 
xpathselector = 'body/ul'

#List of lxml items that need to be decoded
hold = tree.xpath(xpathselector)

'''
1. Get strings of each item in hold
2. Decode to string
3. Remove all tags and \n in each list
4. Split on spaces to create list of lists
'''
df = pd.DataFrame([re.sub('(\\n)|(\<.{0,3}\>)','',etree.tostring(i).decode('utf-8')).split() for i in hold])
df
       0      1        2
0   Name   Many  Stories
1   More   None     None
2  Stuff  About     None
...