MENU

jQueryでYQLを使ってクロスドメインなWebサイトをスクレイピングする

昔はYahoo Pipesというサービスを使って、スクレイピングできたのですが、いつのまにかサービスが終了していました。その代わりとして同じくYahooが提供しているYQLというサービスで同様のことができたのでその方法を紹介します。

デモ

http://ithat.me/wp-content/uploads/2016/12/only-js-web-scraping-with-yql.html

今回は、例としてNAVERまとめの人気記事を取得して表示させたいと思います。

準備

取得したい部分

only-js-web-scraping-with-yql-1

右クリック/検証で開発者ツールを表示して、スクレイピングしたい部分がどういう構成をしているか調べます。すると、mdTopMTMList01Item というブロックが並んでいることが分かります。よって、この部分をスクレイピングすればよいことが分かります。

スクレイピング

全体を取得


$.ajax(
{
  type     : 'GET',
  url      : 'https://query.yahooapis.com/v1/public/yql',
  timeout  : 10000,
  dataType : 'json',
  data     : 
  {
    "q"      : "select * from html where url='https://matome.naver.jp/'",
    "format" : "json"
  }
})
.done(function(data)
{
  console.log(data);
});

select * from… というところがまさにSQL文ですね。url= に取得したいURLを記述します。

only-js-web-scraping-with-yql-2

こんな感じで results に全ページをJSON化したデータが入っています。しかし、毎回全データを取得していてはレスポンスに時間がかかります。今回のように特定の場所(人気記事)だけ取り出したい場合は、一部だけ取り出すように設定する必要があります。

一部を取得


$.ajax(
{
  type     : 'GET',
  url      : 'https://query.yahooapis.com/v1/public/yql',
  timeout  : 10000,
  dataType : 'json',
  data     : 
  {
    "q"      : "select * from html where url='https://matome.naver.jp/' and xpath='//li[@class=\"mdTopMTMList01Item\"]'",
    "format" : "json"
  }
})
.done(function(data)
{
  console.log(data);
});

xpath= の部分でxpath式を使って絞り込むことができます。今回は、mdTopMTMList01Item クラスのみを抜き出したいので、//li[@class=\”mdTopMTMList01Item\”] というように指定します。xpath式について詳しく知りたい方は以下の記事が参考になると思います。

PHPネイティブのDOMによるスクレイピング入門#Xpath式

データを整形する

まず1記事分取得


$.ajax(
{
  type     : 'GET',
  url      : 'https://query.yahooapis.com/v1/public/yql',
  timeout  : 10000,
  dataType : 'json',
  data     : 
  {
    "q"      : "select * from html where url='https://matome.naver.jp/' and xpath='//li[@class=\"mdTopMTMList01Item\"]'",
    "format" : "json"
  }
})
.done(function(data)
{
  // タイトル
  console.log(data.query.results.li[0].div[1].h3.a.content);
  
  // リンク
  console.log(data.query.results.li[0].div[1].h3.a.href);
  
  // 閲覧数
  console.log(data.query.results.li[0].div[1].div.p[1].span[0].content);
});

人気記事は20個取得できるので、ループで回せばよいのですが、目的のデータまでの階層がかなり深いのでまずは最初の1記事だけ取り出してみました。JSONのデータの取り出し方は以下の記事が非常に参考になると思います。

jQueryでjsonデータを扱ってみる【入門編】

ループで回す


.response 要素にデータを挿入します。


$.ajax(
{
  type     : 'GET',
  url      : 'https://query.yahooapis.com/v1/public/yql',
  timeout  : 10000,
  dataType : 'json',
  data     : 
  {
    "q"      : "select * from html where url='https://matome.naver.jp/' and xpath='//li[@class=\"mdTopMTMList01Item\"]'",
    "format" : "json"
  }
})
.done(function(data)
{
  var result = '';
  
  for (var i in data.query.results.li)
  {
    result += '';
  }
  
  $('.response').append(result);
});

これで、自由な形式でHTMLを出力できます。