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

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

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

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

Python 3.x

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

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

Q&A

解決済

1回答

1181閲覧

PyQueryでUnicodeDecodeエラーが起こる

con2319

総合スコア51

スクレイピング

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

Python 3.x

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

Unicode

Unicodeはエンコーディングの標準規格です。1つの文字コード体系で多国語の表現を可能にすることを目指して作られています。

0グッド

0クリップ

投稿2022/01/13 11:44

<実現したい事>
PyQueryを使って指定したファイルからurlとそのタイトルを抜き出す。

<今やったこと>
ファイル指定時にENCODING="UTF-8"エンコードを指定した。
ファイルを開いてからPyQueryに渡した。
with open('dp.html',encoding='utf-8') as f:
d = pq(filename=f )
ちなみにhtmlファイルには <meta charset="UTF-8">が設定してありました。

<起きているエラー>
UnicodeDecodeError: 'cp932' codec can't decode byte 0x8d in position 147: illegal multibyte sequence

python

1from pyquery import PyQuery as pq 2 3 4d = pq(filename='dp.html',encoding='utf8') 5d.make_links_absolute('https://gihyo.jp/dp') 6for a in d('#listBook > li > a[itemprop="url"]'): 7 url = d(a).attr('href') 8 p = d(a).find('p[itemprop="name"]').eq(0) 9 title = p.text() 10 11print(url,title)

誰かわかる方教えてください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ファイルに保存するのではなく requests パッケージを使ってみてはどうでしょうか。

python

1import requests 2from pyquery import PyQuery as pq 3 4url = 'https://gihyo.jp/dp' 5r = requests.get(url) 6r.encoding = r.apparent_encoding 7d = pq(r.text) 8d.make_links_absolute(url) 9for a in d('#listBook > li > a[itemprop="url"]'): 10 url = d(a).attr('href') 11 p = d(a).find('p[itemprop="name"]').eq(0) 12 title = p.text() 13 14print(f'{url=}') 15print(f'{title=}') 16 17# 18url='https://gihyo.jp/dp/ebook/2021/978-4-297-12527-1' 19title='情報処理安全確保支援士試験 令和\n04\n年\n【春期】\n情報処理安全確保支援士 パーフェクトラーニング過去問題集'

投稿2022/01/14 00:53

melian

総合スコア19771

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

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

con2319

2022/01/14 07:49

一応文字列ならできるみたいなのでrequestsを使えばできそうです。 ただできれば、filename='faile path'でやるやり方も一応確認したいのですが 解決に思い当たる節がありませんかね?
melian

2022/01/14 08:56 編集

PyQuery のソースコードを読んでみたのですが、filename キーワードが指定されると encoding キーワードが無視されます。そうなりますと、 UnicodeDecodeError: 'cp932' codec can't decode byte 0x8d in position 147: illegal multibyte sequence というエラーメッセージを回避するためには Python のでデフォルトのエンコーディングを一時的に変更する対応が考えられます。というわけで、以下を追加してみて下さい。 import locale locale.setlocale(locale.LC_ALL, 'ja_JP.UTF-8') 手元に Windows 環境がないので確認が取れないので上手く行くかどうかは不明です。
con2319

2022/01/14 15:47

ありがとうございます。やってみたのですがやっぱり下記のようなエラーが出てしまいました。 Traceback (most recent call last): File "C:\Users\user\Desktop\scrape\3_2_scrape.py", line 11, in <module> d = pq(filename='dp.html') File "C:\Users\user\.virtualenvs\scrape-N3yp2Htl\lib\site-packages\pyquery\pyquery.py", line 192, in __init__ elements = fromstring(html, self.parser) File "C:\Users\user\.virtualenvs\scrape-N3yp2Htl\lib\site-packages\pyquery\pyquery.py", line 57, in fromstring result = getattr(etree, meth)(context) File "src\lxml\etree.pyx", line 3536, in lxml.etree.parse File "src\lxml\parser.pxi", line 1896, in lxml.etree._parseDocument File "src\lxml\parser.pxi", line 1916, in lxml.etree._parseFilelikeDocument File "src\lxml\parser.pxi", line 1811, in lxml.etree._parseDocFromFilelike File "src\lxml\parser.pxi", line 1201, in lxml.etree._BaseParser._parseDocFromFilelike File "src\lxml\parser.pxi", line 615, in lxml.etree._ParserContext._handleParseResultDoc File "src\lxml\parser.pxi", line 721, in lxml.etree._handleParseResult File "src\lxml\etree.pyx", line 333, in lxml.etree._ExceptionContext._raise_if_stored File "src\lxml\parser.pxi", line 370, in lxml.etree._FileReaderContext.copyToBuffer UnicodeDecodeError: 'cp932' codec can't decode byte 0x8d in position 147: illegal multibyte sequence
melian

2022/01/15 01:15

ダメでしたか。。何か判りましたらコメントします。
con2319

2022/01/15 03:28

ありがとうございます。 とりあえず、request経由などの文字列指定だけなら問題なさそうなのでそれでやってみます。 ちなみに確認したソースコードのリンクを教えていただけませんか? 宜しくお願い致します。
melian

2022/01/15 03:46 編集

実は今までローカルに pip でインストールした PyQuery のソースコードを見ていたのですが、先程 github のリポジトリで最新版のソースコードを確認したところ、filename キーワードを指定する場合でも encoding キーワードを見てくれる様なパッチが当たっていました。 encoding kwargs · gawel/pyquery@771b767 https://github.com/gawel/pyquery/commit/771b767c879223e83333a0884ca00d87f16fff55#diff-ce05679f2d1acb64a7c58bc30d40803cd4235ed9bd1ee143b54a59985bf92db2 なので、PyQuery を最新版にアップデートすればエラーが解消されるかもしれません。
con2319

2022/01/15 05:16

一応下記のように記載したのですがダメそうでした。 d = pq(filename='dp.html',encoding='utf-8') 記述方法が違うのですかね?
melian

2022/01/15 05:57

それで正しいです。こちらは Linux 環境なのですが、encoding を意図的に cp932 に指定してみると同じエラーが発生します(utf-8 では問題なし)。 d = pq(filename='dp.html', encoding='cp932') ところで、私の方では PyQuery 最新版のインストールを以下で行いました。 pip install git+https://github.com/gawel/pyquery バージョンは pyquery-2.0.0.dev0 になります。
con2319

2022/01/15 14:04

報告遅くなりました!仮想環境から全て見直したのですがpyqueryのバージョンが1.4.3でエンコーディングに対応してなかったです。それでバージョンアップしたのですがちゃんと機能せず、pipenvを確認してみたらpipenvの対応できるヴァージョンが1.4.3まででurlから直接インストールすることができないみたいなので仮想環境管理をvirtualenvにして1から仮想環境を用意したらちゃんと動作しました!ありがとうございます!なのでバージョンがダメだったみたいです。ちなみにvitualenvをaws上にデプロイした後でも仮想環境はちゃんと働くのですか?わかれば教えていただきたいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問