2017-10-20 3 views
1

私はbeautifulsoupのfindAll関数を使用してテキストのWebページをスクラップし、結果をリストに返します。何らかの理由で、tdコンテナにリンクがある場合、エントリを返しません。たとえば:Beautifulsoup - findAllもリンクがコンテナ内にあるときに文字列を見つけられません

<html 
<tr> 
<td> 
    Taken at. string without link, this is found 
</td> 
</tr> 
<tr> 
<td> 
    Taken at. string followed by link, this is not found 
    <a href="http://www.thisisalink.com/index.html"> 
    text for link 
    </a> 
</td> 
</tr> 
</html> 

最初tdコンテナが返されますが、リンクを含む第二には、次のコードではない:

import requests 
from bs4 import BeautifulSoup 
import re 

genus = 'Parsonsia' 
species = 'straminea' 

page = requests.get("https://www.anbg.gov.au/cgi-bin/apiiName?030=" + genus + "+" + species) 
soup = BeautifulSoup(page.content, 'html.parser') 

grep_str = '^Taken at.*$' 
pattern = re.compile(grep_str) 
location = soup.findAll('td', text=pattern) 

for item in location: 
    print(item) 

私は両方のインスタンスを返すためのfindAll機能を取得するにはどうすればよいですか?結果は、他のスクラップされたデータとのdata.frameに配置されているので、これらのインスタンスをすべて正しい順序で一度に見つけることが重要です。

乾杯!

+0

それは私ではなく、さらに最初の 'td'コンテナ – RomanPerekhrest

+0

謝罪、現在のコードでは何も返しません例はコードを壊しているに違いありません。私は質問を編集させてください。 –

+0

@RomanPerekhrestコードが機能していなかったことを指摘してくれてありがとう。今すぐ働かなければならない。 –

答えて

1

は確かに、私はケースをテストしてみたし、BeautifulSoupが期待される結果が得られていないようです:

は、これは30の植物のリスト全体をプリントアウトできます。代わりに
使用lxml.htmlライブラリ:

import lxml.html as html 
import requests 

genus = 'Parsonsia' 
species = 'straminea' 

page = requests.get("https://www.anbg.gov.au/cgi-bin/apiiName?030=" + genus + "+" + species) 
root = html.fromstring(page.content) 
for td in root.xpath("//td[contains(text(),'Taken at')]"): 
    print(td.text_content()) 

実際の出力:

Taken at. ANBG nursery 
Taken at. ANBG 
Taken at. ANBG 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Back Hillston Rd, near Goolgowi, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. Tuross Head, near Memorial Gardens, Tuross, NSW 
Taken at. Tuross Head, near Memorial Gardens, Tuross, NSW 
Taken at. Lake Conjola beach, N of Ulladulla, NSW 
Taken at. Chain Valley Bay, Lake Macquarie State Conservation Area, NSW 
Taken at. Chain Valley Bay, Lake Macquarie State Conservation Area, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 

http://lxml.de/lxmlhtml.html

+0

ありがとうローマ。私はそのパッケージに慣れる必要があります。 –

1

これは興味深いです。私はなぜそれが起こるのか分からないが、ここに回避策がある。

最初にすべてのtdタグをリストにプルし、そのタグに含まれているテキストに基づいてフィルタリングすることができます。

td_all = soup.findAll('td') 
location = list(filter(lambda td: 'Taken at.' in td.text, td_all)) 

あなたは一度だけあなたのコード内locationを反復処理するつもりなら、それはlist変換を削除し、あなたのループ内で直接filterオブジェクトを使用することをお勧めします:

location = filter(lambda td: 'Taken at.' in td.text, td_all) 

編集:代替ソリューション

スクラップしようとしているページが十分に構造化されています。したがって、少なくともあなたの質問で言及したページのためにそれをナビゲートするのは簡単です。

各画像インデックスはtrに含まれているので、最初にすべての画像インデックスをリストに取り込むことができます。しかし、これらの各要素の中にネストされたテーブルがあるので、findAllメソッドのrecursive=False引数を使用して実行できる直接的な子のみをフェッチする必要があります。

trows = soup.table.tbody.findAll('tr', recursive=False) 

for trow in trows[1:]: 
    print(trow.findAll('tr')[1].td.text) 

最初のものがヘッダー行であるため、リストの2番目の項目からのみ繰り返しました。

Taken at. ANBG nursery 
Taken at. ANBG 
Taken at. ANBG 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Robertson to Belmore Falls Road, NSW 
Taken at. Back Hillston Rd, near Goolgowi, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. shoreline, Tuross Head, NSW 
Taken at. Tuross Head, near Memorial Gardens, Tuross, NSW 
Taken at. Tuross Head, near Memorial Gardens, Tuross, NSW 
Taken at. Lake Conjola beach, N of Ulladulla, NSW 
Taken at. Chain Valley Bay, Lake Macquarie State Conservation Area, NSW 
Taken at. Chain Valley Bay, Lake Macquarie State Conservation Area, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Wright's Lookout walk, New England Nat Pk, NSW 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. Boondall Wet Lands, Brisbane QLD 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
Taken at. see Australian Tropical Rainforest Plants Key 
関連する問題