はじめに

PyQueryは、HTML をJQueryライクに扱えるようにするライブラリである。
スクレイピングをする上で同じようなことは、BeautifulSoup でもできる。
BeautifulSoup の使用方法については、以下の記事を参考にしたい。
[Python] BeautifulSoup で Webスクレイピングをしてみる

また、個人的に PyQuery のほうがシンプルにコードを書けると感じているが、機能は BeautifulSoup のほうが多い。

本稿では、PyQueryを使用して HTML から情報を抽出する方法を説明する。

インストール

% sudo pip install pyquery

使用するhtml

今回使用する HTML は以下になる。

from pyquery import PyQuery as pq

html = """
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>

    <h1 id="test-id" class="test-class">Test Text</h1>

    <a href="http://zombie-hunting-club.com">ゾンビ狩りクラブ</a>

    <ul>
        <li>item1</li>
        <li>item2</li>
        <li>item3</li>
    </ul>

    <div id="div1">
        <p class="p1">pタグ内のテキスト1</p>
    </div>

    <div id="div2">
        <p class="p2">pタグ内のテキスト2</p>
    </div>

  </body>
</html>
"""

今回は直接文字列に書き込んでいるが、どっかのサイトから持ってくる場合は、以下のようにインスタンスを作成するか、Requests や selenium + Phantom.js なんかで HTML を取得する。

pq(url='http://google.com')

PyQueryインスタンスの生成

PyQueryインスタンスを生成することで、操作が行えるようになる。

query = pq(html, parser='html')
print(type(query))
# <class 'pyquery.pyquery.PyQuery'>

print(query)
# <html>
#   <head>
#   </head>
#   <body>
#
#     <h1 id="test-id" class="test-class">Test Text</h1>
#
#     <a href="http://zombie-hunting-club.com">ゾンビ狩りクラブ</a>
#
#     <ul>
#         <li>item1</li>
#         <li>item2</li>
#         <li>item3</li>
#     </ul>
#
#     <div id="div1">
#         <p class="p1">pタグ内のテキスト1</p>
#     </div>
#
#     <div id="div2">
#         <p class="p2">pタグ内のテキスト2</p>
#     </div>
#
#   </body>
# </html>

要素の検索

要素の検索は、多くがJQueryの構文と同じであるので、ここでは一部を紹介する。

タグから検索

タグから検索する方法は、以下の2種類ある。

query.find("h1")
query("h1")
print(type(query("h1")))
# <class 'pyquery.pyquery.PyQuery'>

print(query("h1"))
# <h1 id="test-id" class="test-class">Test Text</h1>

idから検索

print(query("#test-id")) # id
# <h1 id="test-id" class="test-class">Test Text</h1>

classから検索

print(query(".test-class")) # class
# <h1 id="test-id" class="test-class">Test Text</h1>

print(query("#div1 > p"))
# <p class="p1">pタグ内のテキスト1</p>

テキストから検索

print(query("h1:contains('Test Text')"))
# <h1 id="test-id" class="test-class">Test Text</h1>

URLから検索

完全一致

print(query("a[href = 'http://zombie-hunting-club.com']"))
# <a href="http://zombie-hunting-club.com">ゾンビ狩りクラブ</a>

URLに "zombie" が含まれるものに一致

print(query("a[href *= 'zombie']"))
# <a href="http://zombie-hunting-club.com">ゾンビ狩りクラブ</a>

取得

テキストを取得

print(query("h1").text())
# Test Text

id や class, URL などの属性を取得

print(query("h1").attr("id"))
# test-id

print(query("h1").attr("class"))
# test-class

print(query("a").attr('href'))
# http://zombie-hunting-club.com

または、

print(query("h1").attr.id)
# test-id

print(query("h1").attr.class_)
# test-class

n番目の要素を取得

print(query("p"))
# <p class="p1">pタグ内のテキスト1</p>
# <p class="p2">pタグ内のテキスト2</p>

print(query("p").eq(0))
# <p class="p1">pタグ内のテキスト1</p>

print(query("p").eq(1))
# <p class="p2">pタグ内のテキスト2</p>

子要素の取得

print(query("div").children())
# <p class="p1">pタグ内のテキスト1</p>
# <p class="p2">pタグ内のテキスト2</p>

複数要素がマッチした場合

以下のように、複数マッチする場合、for文を使用することができる。

print(query("p"))
# <p class="p1">pタグ内のテキスト1</p>
# <p class="p2">pタグ内のテキスト2</p>

for x in query("p"):
    text = pq(x).text()
    print(text)
# pタグ内のテキスト1
# pタグ内のテキスト2

filter

要素をフィルタすることができる。

print(query("p").filter(lambda x: "テキスト1" in pq(this).text())) # テキストに "テキスト1" が入っている要素のみ抽出する
# <p class="p1">pタグ内のテキスト1</p>

参考


0件のコメント

コメントを残す

アバタープレースホルダー

メールアドレスが公開されることはありません。 が付いている欄は必須項目です