Yahoo!ニュースって「エンタメ」に偏りすぎじゃない?
「ひろゆき」「ゆたぽん」「堀江貴文」「かじさっく」を ニュースで客に見させる目的って何なの?
次の表は、とある一週間「アメリカ」「イギリス」「日本」の『Yahoo!』を開くと出てくる「トップニュース」のカテゴリーの割合を比べたもの。
※株式会社NEUS調べ
日本 | イギリス | アメリカ | |
---|---|---|---|
世界のニュース | 17% | 22% | 24% |
自国のニュース | 38% | 51% | 65% |
スポーツニュース | 9% | 15% | 7% |
芸能ニュース | 35% | 12% | 3% |
その他 | 1% | 0% | 1% |
ゴシップ大好き Yahoo!ニュース
そんな偏向ばりばりの「日本のYahoo!ニュース」
なのだが、トップニュースの選定基準に関して以前テレビで社員が説明していた。
最もPV数が増えそうなニュースがトップに来るように選定している。
ただし、そうするとエンタメだけになるので、時事ニュース等を織り交ぜている。
ようするに、
Yahoo!ニュースの選定は日本国民の嗜好そのもの
世界で戦争が起きようが、選挙があろうが
日本国民はゴシップさえあれば、何もいらない!
そう、君たちのような下級国民は
「課金ゲームをする」
「ゴシップを読む」
ことに時間を費やして、
朝から晩まで社会でこき使われて
名前も残せず人生が終わるんだろうよwww
私は、
下級国民が喜びそうな記事をアップし、
下級国民を働かせて収益を得るビジネスモデル
を確立したからね。
あぁ、ワタシは「上級国民」。
おかけで、毎月遊んで過ごしても
毎月15円が半永久的に入ってくるからね!
そして私のような上級国民ともなると、
有名すぎて勝手に5ちゃんねるでスレだって立つからね。
弁護士に質問したら一つの記事削除に「15万円」と言われたわ……(泣
ネットの収益で賄うと800年かかっても1記事も削除できない……。
Yahoo!ニュースは個人的なコメントを書ける事が一つの売りだ。
偏光記事を信じそうになっても、コメントが指摘をしてくれる。
そして、良いコメントは「そう思う」ボタンを押して支持も可能だ。
なので、「そう思う」の高いユーザをランキングするサービスを運営している。
このサービスの中身の仕組は「Webスクレイピング」だ。
ある日、このサービスに問題が発生した。
事の発端。問題の発生と発見
偶然サービスを確認して気がついた。
あれ?
何も文章が表示されてない?
このような事はよくある。
今までも10回以上は修正してきた。
Webスクレイピングは今や当たり前の技術。
でも、この技術で作ったサイトは一生メンテナンスが必要だ。
相手側がサイトのデザインを変えたら、それに合わせてパース方法を変える必要があるためだ。
問題原因を突き止める
静的ページであればPHPのfile_get_contentsでURLの先の情報を取得することができる。
1 2 3 4 5 6 |
$str = file_get_contents('https://www.google.com/'); echo $str; ?> |
あとは正規表現を使って取り出したい文字列を抽出すればよい。
今までは、相手のサイトデザイン変更に伴い正規表現を修正してきた。
この方法には一つの問題がある。
動的なサイトではスクレイピングのタイミングが早すぎてサイト情報が全て読み込まれない。
例えばAjaxでデータを読み込むサイトの場合は、JSスクリプトが実行されないためデータが取得できない。
今回のYahoo!ニュースのスクレイピング失敗理由は、このAjaxでコメントデータを読み出す仕組みになったのが原因のようだ。
マジか……。
この場合、Seleniumを使ってWEB画面を操作しデータをスクレイピングする方法が有名だ。
この方法には、Chromeをインストールして、ChromeDriverが必要になる。
1 2 3 4 5 6 7 8 9 10 11 |
import time from selenium import webdriver driver = webdriver.Chrome() driver.get('https://www.google.com/') time.sleep(5) search_box = driver.find_element_by_name("q") search_box.send_keys('ChromeDriver') search_box.submit() time.sleep(5) driver.quit() |
ただし、「さくらレンタルサーバー」上でChromedriveを実行しようとすると正しく動作しなかった……。
これは、ローカルPCでSeleniumを動作させて、取得したデータをレンタルサーバーに送信する……
という荒業で凌ぐことは可能だ。
ただ、二重メンテになるので、極力やりたくない。
もう一つの方法として、
通信経路を特定して、実際に叩いているAPIとかURLを送りつける……
という方法がある。
これはパケットのやり取りを理解しないといけない。
でも試してみるかーー。
通信経路を特定する
昔はWiresharkなどを使っていたが、今ではChromeの開発者ツールで通信を確認できる。
まず、GET/POSTの要求に対して、コメントデータを受け取っているパケットを見つける必要がある。
見つけたら、GETに書かれているURLをブラウザ上で打ち込んでみよう。
https://news.yahoo.co.jp/api/profileComment/users/(ユーザID)–?start=1&results=10&isCommentator=false&token=(トークン番号?)
コメントがJSON形式で取得できた!
やった!
これなら簡単に修正できるかも!
やってみたら「Forbidden」が返ってきた
さてURLに書かれている
長いトークン番号
は一体何だろう?
幾らでも長くても手打ちじゃ無いから構わないけどね。
ファミコンジャンプのパスワードには泣かされたなぁ。
呼び出し元のHTMLのファイルの中には、同じ文字列が存在しているので、ブラウザがサイトにアクセスした瞬間に自動で割り振っているモノだと思う。
ただ、PHPからトークン番号を抽出してURLを生成し、アクセスしてみると次の結果が返ってきた。
1 |
{"message":"Forbidden"} |
なんだろう?
スクレイピング対策でもされてるのかなぁ……。
とりあえず常用対策であるブラウザのUser-Agentを付けてみた。
1 2 3 4 5 6 7 |
$ctx = stream_context_create(array( 'http' => array( 'method' => 'GET', 'header' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36') ) ); $webpage = file_get_contents($url,false,$ctx); |
するとコメントが取得できた!
なお、IEのUser-Agentでアクセスして生成されたトークン番号では駄目だった。
ここまで出来れば、JSONファイルを連想配列に読み込み該当箇所を取り出せば修正完了!
まとめ
スクレイピング対策などが増えて対応が日々難しくなっている中で、レンタルサーバー上で解決できたのは嬉しい限りだ。
このように、苦労して運用しているサービスだけど、数人しか使ってないっぽいけどねww。