3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Scrapyのセレクターでテキストを取得

Posted at

取得対象のHTML

このHTMLのpタグ、およびdivタグのテキストをScrapyセレクターで取得する場合の取り方

<div class="info">
  住所: 東京都千代田区丸の内一丁目1ー1<br/>丸の内オフィスビル1F
  <p>TEL: 03-1234-5678</p>
  営業時間: 10:00〜20:00
</div>

pタグのテキストを取得する

In [1]: html = """<div class="info">
   ...:   住所: 東京都千代田区丸の内一丁目<br/> 丸の内オフィスビル1F
   ...:   <p>TEL: 03-1234-5678</p> 営業時間: 10:0020:00
   ...: </div>"""

In [2]: import scrapy
   ...: sel = scrapy.Selector(text=html)

p::textでpタグの文字を取得できる

In [3]: sel.css("div.info p::text").get()
Out[3]: 'TEL: 03-1234-5678'

divタグのテキストを取得する

タグの中身がテキストだけなら良いが、brやpなど内部にタグがあるとdiv::textではすべてを取得できない

pタグの時と同じようにget()を使うとbrタグの手前までの文字しか取得できない。

In [4]: sel.css("div::text").get()
Out[4]: '\n  住所: 東京都千代田区丸の内一丁目'

getall()メソッドでヒットした文字列のリストを取得できるので、これをjoinすれば1つのテキストになる。
ただしdiv::textではdivタグ直下のテキストしかヒットしないのでpタグ(TEL)の文字列が取れない

# getallでヒットしたテキストのリストを取得
In [5]: sel.css("div::text").getall()
Out[5]: ['\n  住所: 東京都千代田区丸の内一丁目', ' 丸の内オフィスビル1F\n  ', ' 営業時間: 10:00〜20:00\n']

# joinで結合
In [6]: "".join(sel.css("div::text").getall())
Out[6]: '\n  住所: 東京都千代田区丸の内一丁目 丸の内オフィスビル1F\n   営業時間: 10:00〜20:00\n'

div *::textを使えばdivタグ以下のテキストにヒットさせることができる。

In [7]: sel.css("div *::text").getall()
Out[7]: 
['\n  住所: 東京都千代田区丸の内一丁目',
 ' 丸の内オフィスビル1F\n  ',
 'TEL: 03-1234-5678',
 ' 営業時間: 10:00〜20:00\n']

In [8]: "".join(sel.css("div *::text").getall())
Out[8]: '\n  住所: 東京都千代田区丸の内一丁目 丸の内オフィスビル1F\n  TEL: 03-1234-5678 営業時間: 10:00〜20:00\n'

::textを使わずxpathのstring()メソッドを使うことでも指定要素のテキストを取得できる

In [9]: sel.css("div").xpath("string()").get()
Out[9]: '\n  住所: 東京都千代田区丸の内一丁目 丸の内オフィスビル1F\n  TEL: 03-1234-5678 営業時間: 10:00〜20:00\n'

(BeautifulSoupの場合の取り方)

BeautifulSoupだとtextプロパティで内部にタグがあってもテキスト取得できるので、
それと同じ感じでScrapyを使うと取りこぼすかも

In [1]: html = """<div class="info">
   ...:   住所: 東京都千代田区丸の内一丁目<br/> 丸の内オフィスビル1F
   ...:   <p>TEL: 03-1234-5678</p> 営業時間: 10:0020:00
   ...: </div>"""

In [2]: from bs4 import BeautifulSoup
   ...: soup = BeautifulSoup(html, "html.parser")

# textプロパティでdiv要素以下の文字列を取得できる
In [3]: soup.select_one("div").text
Out[3]: '\n  住所: 東京都千代田区丸の内一丁目 丸の内オフィスビル1F\n  TEL: 03-1234-5678 営業時間: 10:00〜20:00\n'

参考

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?