スクレイピングのプログラム的備忘録
from bs4 import BeautifulSoup import pandas as pd
HTMLのサンプル
html = """ <div class="entry_contents"> <h1>h1要素です</h1> <h2>h1直下のh2要素です</h2> <div class="detail_date">3000/11/11</div> <span class="category"><a href="https://www.yahoo.co.jp/">スクレイピング</a></span> <div class="text_contents"> <p id="p1">Pタグの1行目</p> <img loading="lazy" src="***.png" alt='一枚目の画像'> <div id="wrapper" class="content"> <p id="p2">なんとかかんとかここに書いてある</p> </div> <h2>h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ</h2> <h1>h1要素の2番めです。変則的にh2の下に入れておきます</h1> <p id="p3">いや、きつねが化けているんや</p> <p id="p4">えー、そうなの?</p> </div> """
内容は気にしないでください。
疲れの極致にて。
リスト内包表記にif文でh1に続く要素がPだったら、タグのテキストだけをリストに追加する。
soup = BeautifulSoup(html, features="lxml") lists = [] [lists.append(tag.text) for tag in soup.h1.next_elements if tag.name == 'p'] lists
select
all_h1 = soup.select('h1') [<h1>h1要素です</h1>, <h1>h1要素の2番めです。変則的にh2の下に入れておきます</h1>]
指定タグ以降の要素を取得
soup.h2.next_elements <generator object PageElement.next_elements at 0x0000027437000F90><br />
イテレータが云々カンヌンにて以下。
for x in soup.h2.next_elements: print('*'*10) print(x)
********** h1直下のh2要素です ********** ********** <div class="detail_date">3000/11/11 <span class="category"><a href="https://www.yahoo.co.jp/">スクレイピング</a></span> </div> ********** 3000/11/11 ********** <span class="category"><a href="https://www.yahoo.co.jp/">スクレイピング</a></span> ********** <a href="https://www.yahoo.co.jp/">スクレイピング</a> ********** スクレイピング ********** ********** ********** <div class="text_contents"> <p id="p1">Pタグの1行目</p> <img alt="一枚目の画像" loading="lazy" src="***.png"/> <div class="content" id="wrapper"> <p id="p2">なんとかかんとかここに書いてある</p> </div> <h2>h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ</h2> <h1>h1要素の2番めです。変則的にh2の下に入れておきます</h1> <p id="p3">いや、きつねが化けているんや</p> <p id="p4">えー、そうなの?</p> </div> ********** ********** <p id="p1">Pタグの1行目</p> ********** Pタグの1行目 ********** ********** <img alt="一枚目の画像" loading="lazy" src="***.png"/> ********** ********** <div class="content" id="wrapper"> <p id="p2">なんとかかんとかここに書いてある</p> </div> ********** ********** <p id="p2">なんとかかんとかここに書いてある</p> ********** なんとかかんとかここに書いてある ********** ********** ********** <h2>h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ</h2> ********** h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ ********** ********** <h1>h1要素の2番めです。変則的にh2の下に入れておきます</h1> ********** h1要素の2番めです。変則的にh2の下に入れておきます ********** ********** <p id="p3">いや、きつねが化けているんや</p> ********** いや、きつねが化けているんや ********** ********** <p id="p4">えー、そうなの?</p> ********** えー、そうなの? ********** **********
リスト内包表記とif
[print(tag.text) for tag in soup.h1.next_elements if tag.name == 'p']
Pタグの1行目 なんとかかんとかここに書いてある いや、きつねが化けているんや えー、そうなの? [None, None, None, None]
要素のあるなし判定(属性)
if soup.div.has_attr('class'): [print(tag.text) for tag in soup.h1.next_elements if tag.name == 'p'] else: print('pass')
Class化
(素人ながら)最終的にどうまとめたかというのがこちらです。
class Tag_Search: def __init__(self): lists = ['test'] def tags_siblings(self): self.lists = [] soup = self.soup tags = soup.find_all(self.tag_target) if tags is None: pass else: #print(tags) for tag in tags: #print(tag.name,tag.text) tag_sib = tag.next_siblings #print(tag_sib,':sib') for sibling in tag_sib: #print(type(sibling)) if sibling.name == 'p': self.lists.append([tag.text,sibling.text]) #print(sibling.name,sibling.text) return self.lists
要素のあるなし判定をifでやっておいて、next_siblingsでターゲット要素の直後の要素と値も取得します。
TS = Tag_Search() TS.soup = BeautifulSoup(html, features="lxml") for tag in ['h1','h2']: TS.tag_target = tag TS.tags_siblings() pd.DataFrame(TS.lists,columns=['h','content'])
p いや、きつねが化けているんや p えー、そうなの? p いや、きつねが化けているんや p えー、そうなの? h content 0 h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ いや、きつねが化けているんや 1 h2:ぽんぽこどう本舗はかわいいたぬきが運営するお店だよ えー、そうなの?
当サイトはリンクフリーです。
ご自身のブログでの引用、TwitterやFacebook、Instagram、Pinterestなどで当サイトの記事URLを共有していただくのは、むしろありがたいことです。
事前連絡や事後の連絡も不要ですが、ご連絡いただければ弊社も貴社のコンテンツを紹介させていただく可能性がございます。