このブログを検索

ラベル utf-8 の投稿を表示しています。 すべての投稿を表示
ラベル utf-8 の投稿を表示しています。 すべての投稿を表示

2019/04/18

python3のcgiでUnicodeEncodeError

腹立つなァ....

python3のcgiで日本語を表示させたらページが真っ白に。

ログを見たら、

UnicodeEncodeError: 'ascii' codec can't encode characters in position...

python2の時はちゃんと動いていたのに。


いろいろ調べた結果、
下記を追加して動いた。

#!/usr/bin/python
import sys #↓以下2行を追加 import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') print( "Content-Type: text/html") print() print('糞野郎')
(参考)
http://lab.knightstyle.info/%E7%A7%81%E3%81%8Cpython3%E3%81%A7unicodeencodeerror%E3%81%AA%E3%81%AE%E3%81%AF%E3%81%A9%E3%81%86%E8%80%83%E3%81%88%E3%81%A6%E3%82%82%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E6%96%87%E5%AD%97/

2019/03/03

python3.6のCGIでGoogleニュースのヘッドラインを抽出するスクレイピング例


python3.6によるスクレイピング例

Googleニュースのヘッドラインのタイトルを抽出する。

beautifulsoupは使わず、正規表現でゴリゴリする。


-------
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import re
import sys
import cgi
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

my_title = 'what\'s hot'

def print_head(title):
    print('Content-type: text/html')
    print()
    print('<html><head>')
    print('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">')
    print('<title>'+title+'</title>')
    print('</head>')

def print_tail():
    print('</html>')

print_head(my_title)

print('<body>')

res = requests.get('https://news.google.com/?hl=ja&gl=JP&ceid=JP%3Aja')
res.raise_for_status()

print("From Google News JP status:" + str(res.status_code) + "<br><br>")

tmp = re.sub('\n','',res.text)
tmp = re.sub('<a href','\n<a href',tmp)
tmp = re.sub('\/a>','/a>\n',tmp)
tmplist = tmp.split('\n')

result = [ s for s in tmplist if re.match('<a href=\"\.\/articles.*?\/a>', s) or ( 'すべての記事' in s ) ]

for i in result:
    if 'すべての記事' in i:
        break
    s = re.sub(r'<a href.*?<span >(.*?)<\/span><\/a>',r'\1',i)
    print(s+"<br>")

print('</body>')

print_tail()

------

苦労したところ

import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

これを入れないと、抽出した結果をprintするときに下記のようなエラーになる。

UnicodeEncodeError: 'ascii' codec can't encode characters in position 343-391: ordinal not in range(128)

googleニュースのヘッドラインだけを抽出したかったのだが、
htmlソースを見ても特定の条件がみつからない。

'<a href=\"\.\/articles.*?\/a>',

で抽出すれば見出しのリンクが取れるのだが、ヘッドライン以外もすべて取れてしまう。

「すべての記事」というキーワードが区切りになっているので、
それが出てくるまで、という条件で抽出した。


これができればどこからでもなんでも取れる....