【问题标题】:web scraping using nested for loops, BeautifulSoup in python3使用嵌套的for循环进行网络抓取,python3中的BeautifulSoup
【发布时间】:2018-01-21 16:49:48
【问题描述】:

我正在抓取一个 html 文件。 我写了以下代码。

with open('Basic Materials.htm') as fp:
    soup=BeautifulSoup(fp,'lxml')
    table=soup.find('div',{'class':'sfe-break-bottom'})
    for row in table.find_all('tr'):
        cells=row.find_all('td')
        print(cells)

现在打印(单元格)的输出如下:

[<td colspan="2" style="text-align:left"><b>Gainers (% price change)</b>
</td>, <td width="15%">Last Trade
</td>, <td width="20%">Change
</td>, <td width="15%">
Mkt Cap
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:GFI&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Gold Fields Limited (ADR)</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:GFI&amp;ei=H7pKWbBtgoabAZ7Kv7gI">GFI</a>
</td>, <td>3.53
</td>, <td width="20%">
<span class="chg">+0.11</span>
<span class="chg">(3.22%)</span>
</td>, <td>2.84B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:VALE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Vale SA (ADR)</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:VALE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">VALE</a>
</td>, <td>7.94
</td>, <td width="20%">
<span class="chg">+0.17</span>
<span class="chg">(2.19%)</span>
</td>, <td>39.61B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:CLF&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Cliffs Natural Resources</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:CLF&amp;ei=H7pKWbBtgoabAZ7Kv7gI">CLF</a>
</td>, <td>5.97
</td>, <td width="20%">
<span class="chg">+0.12</span>
<span class="chg">(2.14%)</span>
</td>, <td>1.69B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:AUY&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Yamana Gold Inc. (USA)</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:AUY&amp;ei=H7pKWbBtgoabAZ7Kv7gI">AUY</a>
</td>, <td>2.40
</td>, <td width="20%">
<span class="chg">+0.05</span>
<span class="chg">(1.91%)</span>
</td>, <td>2.27B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:HL&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Hecla Mining Company</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:HL&amp;ei=H7pKWbBtgoabAZ7Kv7gI">HL</a>
</td>, <td>5.20
</td>, <td width="20%">
<span class="chg">+0.09</span>
<span class="chg">(1.86%)</span>
</td>, <td>2.03B
</td>]
[<td colspan="2" style="text-align:left"><b>Losers (% price change)</b>
</td>, <td colspan="3">
</td>]
[<td style="text-align:left;">
<a href="/finance?cid=717954&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Jaguar Mining Inc (USA)</a>
</td>, <td style="text-align:left;">
<a href="/finance?cid=717954&amp;ei=H7pKWbBtgoabAZ7Kv7gI"></a>
</td>, <td>11.92
</td>, <td width="20%">
<span class="chr">-0.74</span>
<span class="chr">(-5.85%)</span>
</td>, <td>2.52B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:OLN&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Olin Corporation</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:OLN&amp;ei=H7pKWbBtgoabAZ7Kv7gI">OLN</a>
</td>, <td>28.64
</td>, <td width="20%">
<span class="chr">-1.52</span>
<span class="chr">(-5.04%)</span>
</td>, <td>4.81B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NASDAQ:GPRE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Green Plains Inc</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NASDAQ:GPRE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">GPRE</a>
</td>, <td>19.12
</td>, <td width="20%">
<span class="chr">-0.98</span>
<span class="chr">(-4.85%)</span>
</td>, <td>708.77M
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:IPI&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Intrepid Potash, Inc.</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:IPI&amp;ei=H7pKWbBtgoabAZ7Kv7gI">IPI</a>
</td>, <td>2.09
</td>, <td width="20%">
<span class="chr">-0.09</span>
<span class="chr">(-4.13%)</span>
</td>, <td>261.35M
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NASDAQ:CENX&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Century Aluminum Co</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NASDAQ:CENX&amp;ei=H7pKWbBtgoabAZ7Kv7gI">CENX</a>
</td>, <td>13.62
</td>, <td width="20%">
<span class="chr">-0.56</span>
<span class="chr">(-3.95%)</span>
</td>, <td>1.17B
</td>]
[<td colspan="2" style="text-align:left"><b>Most Actives (dollar volume)</b>
</td>, <td colspan="3">
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:X&amp;ei=H7pKWbBtgoabAZ7Kv7gI">United States Steel Corp.</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:X&amp;ei=H7pKWbBtgoabAZ7Kv7gI">X</a>
</td>, <td>21.27
</td>, <td width="20%">
<span class="chg">+0.20</span>
<span class="chg">(0.95%)</span>
</td>, <td>3.77B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:DOW&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Dow Chemical Co</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:DOW&amp;ei=H7pKWbBtgoabAZ7Kv7gI">DOW</a>
</td>, <td>64.01
</td>, <td width="20%">
<span class="chr">-1.09</span>
<span class="chr">(-1.67%)</span>
</td>, <td>78.06B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:NUE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Nucor Corporation</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:NUE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">NUE</a>
</td>, <td>56.15
</td>, <td width="20%">
<span class="chg">+0.02</span>
<span class="chg">(0.04%)</span>
</td>, <td>18.02B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:VALE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">Vale SA (ADR)</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:VALE&amp;ei=H7pKWbBtgoabAZ7Kv7gI">VALE</a>
</td>, <td>7.94
</td>, <td width="20%">
<span class="chg">+0.17</span>
<span class="chg">(2.19%)</span>
</td>, <td>39.61B
</td>]
[<td style="text-align:left;">
<a href="/finance?q=NYSE:MT&amp;ei=H7pKWbBtgoabAZ7Kv7gI">ArcelorMittal SA (ADR)</a>
</td>, <td style="text-align:left;">
<a href="/finance?q=NYSE:MT&amp;ei=H7pKWbBtgoabAZ7Kv7gI">MT</a>
</td>, <td>20.16
</td>, <td width="20%">
<span class="chg">+0.28</span>
<span class="chg">(1.38%)</span>
</td>, <td>20.06B
</td>][/python]

现在我想找到前 3 个“a”标签和这些“a”标签的文本。 所以删除上面代码中的 print(cells) 语句并重新编写代码如下:

[python]
with open('Basic Materials.htm') as fp:
    soup=BeautifulSoup(fp,'lxml')
    table=soup.find('div',{'class':'sfe-break-bottom'})
    for row in table.find_all('tr'):
        cells=row.find_all('td')
        for link in cells.find_all('a', limit=3):
            print(link.get_text()) # gets the name 
            print(link.get('href')) # gets the links

但我收到以下错误

AttributeError Traceback(最近调用 最后的) 在 () 4 对于 table.find_all('tr') 中的行: 5 个细胞=row.find_all('td') ----> 6 用于 cells.find_all('a', limit=3) 中的链接: 7 print(link.get_text()) # 获取名称 8 print(link.get('href')) # 获取链接 ~\Anaconda3\envs\practice\lib\site-packages\bs4\element.py in getattr(self, key) 1805 def getattr(自我,钥匙): 第1806章 -> 1807 “ResultSet 对象没有属性 '%s'。您可能将项目列表视为单个项目。你有没有 当你打算调用 find() 时调用 find_all()?" % key 第1808章 AttributeError:ResultSet 对象没有属性“find_all”。您可能将项目列表视为单个项目。你是否 当你打算调用 find() 时调用 find_all()?

请您告诉我为什么会出现此错误? 如何获得前 3 个“a”和带有这些标签的文本。 谢谢

【问题讨论】:

标签: python-3.x beautifulsoup


【解决方案1】:

cells 是一个列表,因此您不能从中直接调用方法 .findAll,尝试创建一个列表来替换您的意思 cells.find_all('a', limit=3),您可以执行以下操作:

for cell in cells:
    atags = cell.findAll('a',limit=3)
    for link in atags:
        print(link.text)
        print(link['href'])

或使用列表推导:

atags = [cell.findAll('a',limit=3) for cell in cells]
for link in atags:
    print(link[0].text)
    print(link[0]['href'])

【讨论】:

  • @Jonelya 很高兴为您提供帮助,如果可行,请告诉我!
  • 我按照您的指导更改了代码:with open('Basic Materials.htm') as fp: soup=BeautifulSoup(fp,'lxml') table=soup.find('div', {'class':'sfe-break-bottom'}) for table.find_all('tr') 中的行:cells=row.find_all('td') atags = [cell.find_all('a',limit=3 ) 对于单元格中的单元格] 对于 atags 中的链接: print(links.get_text()) print(links.get('href')) 但我再次收到错误消息: AttributeError: ResultSet object has no attribute 'get_text'。
  • @Jonelya 你是对的,检查我的编辑,改用.text
  • 不工作。我也分别尝试了 print(link.text()) 和 print(link['href']) ..但不工作
  • 谢谢你的兄弟......它的工作......非常感谢你
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多