使用lxml.html解析大型html文档

时间:2018-08-01 22:56:53

标签: python html parsing beautifulsoup lxml

<td style="vertical-align:bottom;background-color:#efefef;padding-left:2px;padding-top:2px;padding-bottom:2px;padding-right:2px;">
  <div style="text-indent:26px;font-size:9pt;">
    <font style="font-family:Helvetica,sans-serif;font-size:9pt;">
    iPhone
    </font>
    <font style="font-family:Helvetica,sans-serif;font-size:9pt;">
    <sup style="vertical-align:top;line-height:120%;font-size:pt">
    (1)
    </sup>
    </font>
  </div>
</td>
<td style="vertical-align:bottom;padding-left:2px;padding-top:2px;padding-bottom:2px;background-color:#efefef;">
  <div style="text-align:left;font-size:9pt;">
    <font style="font-family:Helvetica,sans-serif;font-size:9pt;">
    $
    </font>
  </div>
</td>
<td style="vertical-align:bottom;background-color:#efefef;padding-top:2px;padding-bottom:2px;">
  <div style="text-align:right;font-size:9pt;">
    <font style="font-family:Helvetica,sans-serif;font-size:9pt;">
    29,906
    </font>
  </div>
</td>
<td style="vertical-align:bottom;background-color:#efefef;">
  <div style="text-align:left;font-size:10pt;">
    <font style="font-family:inherit;font-size:10pt;">
    <br/>
    </font>
  </div>
</td>

我正在尝试使用lxml来获取两个字段:iPhone和29,906。

这是更大的html文件的一部分。

我已经找到了如何在每个td中提取字体,但是我需要能够匹配iPhone字段和29906字段。

我能想到的一种方法是将所有内容放入一个很长的数组中并搜索“ iPhone”并返回iPhone + 2的值,但这似乎很漫长且效率低下。

有人可以引导我朝正确的方向吗?

这是我到目前为止所拥有的:

from bs4 import BeautifulSoup
import requests
from lxml import html, cssselect

link =    "https://www.sec.gov/Archives/edgar/data/320193/000032019318000100/a10-qq320186302018.htm"
response = requests.get(link)
soup = BeautifulSoup(response.text, 'html.parser')
str_soup = str(soup)
doc = html.document_fromstring(str_soup)
for col in doc.cssselect('font'):
    try:
        style = col.attrib['style']
        if style=="font-family:Helvetica,sans-serif;font-size:9pt;":
            print(col.text.strip())
    except:
        pass

这将返回所有文本,但不是我需要的文本。

2 个答案:

答案 0 :(得分:1)

怎么样?

from bs4 import BeautifulSoup
import re

soup = BeautifulSoup(html, 'html.parser')

x = soup.find_all('font')
name = re.sub(r"[\n\t\s]*", "", x[0].get_text())
value = re.sub(r"[\n\t\s]*", "", x[3].get_text())

print(name, 'costs', value)

输出:

iPhone costs 29,906

答案 1 :(得分:0)

我没有得到我想要的东西,但是到目前为止我可以提出来的东西是基于

from bs4 import BeautifulSoup
import requests
from lxml import html, cssselect
import csv


link = "https://www.sec.gov/Archives/edgar/data/320193/000032019318000100/a10-qq320186302018.htm"
response = requests.get(link)
soup = BeautifulSoup(response.text, 'html.parser')
str_soup = str(soup)
doc = html.document_fromstring(str_soup)


with open('AAPL_financials.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)
    for col in doc.cssselect('tr'):
        row = []
        for text in col.cssselect('font'):
            if text.text == None:
                continue
            value = text.text.strip()
            if value == "":
                continue
            if value == "$":
                continue
            if value == "%":
                continue
            if value == ")":
                continue
            if value[0] == "(":
                value = value.replace("(", "-"))
            row.append(value)
        writer.writerow(row)