質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

1回答

4182閲覧

PyQueryでのスクレイピングで特定のページだけ文字化け

退会済みユーザー

退会済みユーザー

総合スコア0

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2017/04/08 15:32

編集2017/04/08 15:35

練習でPyQueryで大学のシラバスのデータを取得しようとしているのですが、

http://www0.osakafu-u.ac.jp/syllabus/list02.aspx?CD1=3&CD2=601
ここのページのデータだと文字化けせずに取得できるのですが、
上のページから飛んだリンクの先のページ、無数にありますが例えば
http://www0.osakafu-u.ac.jp/syllabus/detail.aspx?CD=103
ここのページをスクレイピングしようとすると日本語が文字化けします。

どちらのページもutf-8が使われていることは確認済みなのですが、
以下のコードのどこに問題があるのでしょうか。

ご存じの方がいれば回答よろしくお願いします。

import

1import chardet 2from pyquery import PyQuery as pq 3 4if __name__ == '__main__' : 5 # Htmlファイル取得 6 opener = urllib.request.build_opener() 7 request = urllib.request.Request('http://www0.osakafu-u.ac.jp/syllabus/list02.aspx?CD1=3&CD2=601') 8 html = opener.open(request).read() 9 10 for li_node in pq(html).find('li'): 11 # liノード取得 12 li_nodes = pq(li_node)('li') 13 # url 14 url = li_nodes.find('a').eq(0).attr('href') 15 URL = 'http://www0.osakafu-u.ac.jp/syllabus/'+ str(url) 16 # title 17 title = li_nodes.eq(0).text() 18 19 opener2 = urllib.request.build_opener() 20 request2 = urllib.request.Request(URL) 21 html2 = opener.open(request2).read() 22 23 for li_node2 in pq(html2).find('div#div_Yu'): 24 25 li_node2 = pq(li_node2)('div#div_Yu').find('tr').eq(1) 26 27 code = li_node2.find('span#lbl_ZYUGYO_CD').text() 28 week = li_node2.find('span#lbl_WJ_NM').text() 29 room = li_node2.find('span#lbl_ROOM_NM').text() 30 teacher = li_node2.find('span#lbl_KYOIN_NM').text() 31 32 # 表示 33 if url and title and code and week and room and teacher: 34 print('[\"'+code+'\",\"'+week+'\",\"'+title+'\",\"'+teacher+'\",\"'+room+'\",\"'+URL+'\"],') 35 36コード

それと、PyQueryの使い方の載った本とかを探してみても見当たらなかったんですが、どこか使い方がわかりやすくまとまっているページとかご存知でないでしょうか。
良ければそちらもお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

文字化けしないページでは、 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> と明確にソース上で UTF-8 であることが示されているのに対し、文字化けするページではそれが無いため、 PyQuery (正確には、その中で使われている lxml) が文字コードの検出に失敗しているせいだと思われます。コードの問題というわけではないでしょう。

UTF-8 であることがわかっているのであれば、 pq(html2.decode('utf-8')) としてデコードしてから渡してやる (とか、無理やりですが pq(b'<meta charset="utf-8" />' + html2) のように文字コードの宣言を追加してやるとかする) と動作するのではないでしょうか。

あるいは、もう少しお行儀よくやるのであれば、ご提示のコードで import している chardet に検出させてから decode() するとか、 Web サーバが返してきたContent-Type ヘッダの値を参考にするとか、そういった実装を検討するとよいように思います。いずれにせよ、先に decode() して渡した方が無難ということになります。

投稿2017/04/08 16:36

argparse

総合スコア1017

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/08 16:49

できました!!!! pq(html2.decode('utf-8')) の方では、 「'PyQuery' object has no attribute 'decode'」とエラーを吐かれたのですが、 pq(b'<meta charset="utf-8" />' + html2)の方ではみごと、文字化けせずに実行されました!! 確かに言われてみれば無理矢理な方法ですが、こういうアイディアもあるんですねww ありがとうございました。2日間くらいずっと解決できずに大変だったので感謝感激です。
argparse

2017/04/08 18:40

動いたようで良かったです。 `'PyQuery' object has no attribute 'decode'` エラーの件ですが、もしかすると、 `pq(html2.decode('utf-8'))` ではなく `pq(html2).decode('utf-8')` になっておりませんでしたか? 一応は `decode()` を使う方が、よりちゃんとした書き方ではあるので、余裕があれば確認してみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問