見出し画像

副業情報を自動で集めて通知するツールを作ろう_2【GAS】【スクレイピング】

 前回でとりあえず動作するツールが作成できました。

今回からは使い勝手を上げていきたいと思います。今回行うのは定期実行です。ついでに別サイトのスクレイピングも追加します。

できるもの:
 ・12時間ごとに自動検索して結果をメール通知する仕組み 
 ・ランサーズ、クラウドワークスの情報収集(スクレイピング)

この記事の対象者

この記事ではこんな方のお悩みに答えます。
・できるだけコピペで簡単に何かを作ってみたい
・スクレイピングのシステムサンプルが欲しい
・定期実行して結果を通知するシステムの仕組みを知りたい
・Google Apps Script(GAS)初心者の方もOK!

では前回の続きから進めたいと思います。

定期実行の設定

GASのトリガーという機能でプログラムを定期的に自動実行することができます。今回は12時間ごとに設定したいと思います。

Googleにログインして前回作成したApps Scriptの画面を開きます。左側のメニューの中からトリガーをクリックします。

画像1

トリガー画面に変わったら、右下の「トリガーを追加」をクリックします。

画像2

トリガー追加画面で次のように設定します。
  実行する関数を選択   → main
  実行するデプロイを選択 → Head
  イベントのソースを選択 → 時間主導型
  時間ベースのトリガータイプを選択 → 時間ベースのタイマー
  時間の間隔を選択(時間)→ 12時間おき
上のように設定して保存ボタンをクリック

画像3

 この設定で12時間ごとに自動で処理されるようになります。
注意が必要なのは何時何分から12時間後とかでなくて、設定操作をした時間から12時間毎になること。例えば10時5分に設定したら「22時5分」と「10時5分」に実行するようになります。思い通りに時間指定するには、トリガーを設定するだけのプログラムを書いて、それを時間指定で実行して、トリガーを再設定する方法がありますがここでは割愛します。

別の副業サイトのスクレイピング処理を追加する

ついでにクラウドワークスからもスクレイピングできるようにしてみます。
プログラム全文 ↓

const SHEET = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
const PAGES = 3;

const main = () => {
	//シートを初期化する
	clearsheet();

	let cnt_Lancers=0,cnt_CrowdWorks=0;
	cnt_CrowdWorks = Scraping_CrowdWorks();
	cnt_lancers = Scraping_Lancers();
	SendMail(cnt_lancers,cnt_CrowdWorks);
}

const Scraping_Lancers = () => {
	let cnt=0;
	//ページ単位でスクレイピング
	for(let page=1;page<=PAGES;page++){
		const url = "https://www.lancers.jp/work/search?sort=client&type%5B0%5D=task&open=1&show_description=1&work_rank%5B0%5D=3&work_rank%5B1%5D=2&work_rank%5B2%5D=0&budget_from=&budget_to=&keyword=%E3%82%A2%E3%83%B3%E3%82%B1%E3%83%BC%E3%83%88&not=&page=${page}".replace("${page}", page);
		const html = UrlFetchApp.fetch(url).getContentText('UTF-8');
		Utilities.sleep(300);
		const workArray = Parser
			.data(html)
			.from('<div class="c-media__content__right">')
			.to('</div>')
			.iterate();

		for(let i =0;i<workArray.length;i++){
			const content = workArray[i];
			//案件タイトル
			const p_title = Parser
				.data(content)
				.from('<span class="c-media__title-inner">')
				.to('</span>')
				.build();
			let workTitle=deleteTag(p_title);

			//詳細リンク
			let workDetailurl='';
			let workNumber='';
			const p_detailurl_pos=content.indexOf('<a class="c-media__title" href="');
			if(p_detailurl_pos != -1){
				const p_detailurl_pos2=content.indexOf('">');
				workDetailurl = "https://www.lancers.jp" + content.substr(p_detailurl_pos+32,p_detailurl_pos2-(p_detailurl_pos+32));
				workNumber = content.substr(p_detailurl_pos+45,p_detailurl_pos2-(p_detailurl_pos+45));
			}

			//報酬額
			let workPayment='';
			const p_workPayment_pos=content.indexOf('<span class="c-media__job-price">');
			if(p_workPayment_pos != -1){
				workPayment = content.substr(p_workPayment_pos);
				workPayment = deleteTag(workPayment);
			}

			//シートに書き込む
			if(workNumber != '' && workTitle!='' && workDetailurl!=''){
				const lastrow = SHEET.getLastRow()+1;
				SHEET.getRange(lastrow,2).setValue(workNumber);
				SHEET.getRange(lastrow,3).setValue(workTitle);
				SHEET.getRange(lastrow,4).setValue(workDetailurl);
				SHEET.getRange(lastrow,5).setValue(workPayment);
				Utilities.sleep(50);
				cnt+=1;
			}
		}
		Utilities.sleep(300);
		//次へのリンクがないときはスクレイピングを終了する
		f(html.indexOf('<span class="pager__item pager__item--next">')==-1){
			break;
		}

	}
	return cnt;
}

const Scraping_CrowdWorks = () => {
	let cnt=0;
	//ページ単位でスクレイピング
	for(let page=1;page<=PAGES;page++){
		const url = "https://crowdworks.jp/public/jobs/search?hide_expired=true&keep_search_criteria=true&order=new&page=${page}&payment_type=task&search%5Bkeywords%5D=%E3%82%A2%E3%83%B3%E3%82%B1%E3%83%BC%E3%83%88".replace("${page}", page);
		const html = UrlFetchApp.fetch(url).getContentText('UTF-8');
		Utilities.sleep(300);
		const workArray = Parser
			.data(html)
			.from('<div class="job_data_row">')
			.to('<span class="absolute_date">')
			.iterate();

		for(let i =0;i<workArray.length ;i++){
			const content = workArray[i];
			//案件タイトル
			const p_title = Parser
				.data(content)
				.from('<h3 class="item_title">')
				.to('</h3>')
				.build();
			let workTitle=deleteTag(p_title);

			//詳細リンク
			let workDetailurl='';
			let workNumber='';
			const p_detailurl_pos=content.indexOf('<a data-item-title-link="" target="_blank" rel="noopener noreferrer" href="');
			if(p_detailurl_pos != -1){
				const temp =content.substr(p_detailurl_pos);
				const p_detailurl_pos2=temp.indexOf('">');
				workDetailurl = "https://crowdworks.jp/" + temp.substr(76,p_detailurl_pos2-76);
				workNumber = temp.substr(88,p_detailurl_pos2-88);
			}

			//報酬額
			let workPayment='';
			const p_workPayment_pos=content.indexOf('<b class="amount">');
			if(p_workPayment_pos != -1){
				workPayment=content.substr(p_workPayment_pos);
				workPayment = deleteTag(workPayment);
			}

			//シートに書き込む
			if(workNumber != '' && workTitle!='' && workDetailurl!=''){
				const lastrow = SHEET.getLastRow()+1;
				SHEET.getRange(lastrow,2).setValue(workNumber);
				SHEET.getRange(lastrow,3).setValue(workTitle);
				SHEET.getRange(lastrow,4).setValue(workDetailurl);
				SHEET.getRange(lastrow,5).setValue(workPayment);
				Utilities.sleep(50);
				cnt+=1;
			}
		}
		Utilities.sleep(300);

		//次へのリンクがないときはスクレイピングを終了する
		if(html.indexOf('gtm_event_label="「次のページへ」ボタン"')==-1){
			break;
		}
	}
	return cnt;
}

const clearsheet = () => {
	const lastrow = SHEET.getLastRow();
	if(lastrow-4 > 0) {
		SHEET.getRange(5,1,lastrow-4,10).setValue("");
	}
}

const deleteTag = (str) => {
	let ret=str.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'')
	ret = ret.replace(/[\s\t\n]/g,"");
	return ret;
}

const SendMail = (cnt_lancers,cnt_CrowdWorks) => {
	//案件検索結果

	// 送信時間
	const today = Utilities.formatDate(new Date(), 'JST', 'yyyy年M月d日 H時m分s秒');
	// メールタイトル
	const subject	 = "案件検索結果"+today;
	//送信先メールアドレス
	const address = Session.getActiveUser().getEmail(); //あなたのメールアドレス 
	//メール本文
	const link_sheet = SpreadsheetApp.getActiveSpreadsheet().getUrl();
	const body = "ランサーズ"+cnt_lancers+"件\n"+"クラウドワークス"+cnt_CrowdWorks+"件\n\n"+link_sheet;
	const mailbody = "お疲れ様です。\n本日"+today+"時点での検索結果を送ります。\n"+ body + "\n";

	GmailApp.sendEmail(address,subject,mailbody);
}


12時間ごとに下のようなメールが届くようになったら成功です。
文中のURLをクリックしたらスプレッドシートが開きます。

画像4


予告
 自動実行され、2か所からスクレイピングできるようになったのでだいぶ使えるツールになりましたね。
 次回は他の人にも配信できるようにメール配信先設定シートを作って複数先に送れるようにしたいと思います。


#スクレイピング #プログラミング #GAS #副業 #自動化ツール #無料配布 #コピペで使えるGAS  #GoogleAppsScript #クラウドワークス #ランサーズ

おススメの本

 GASを勉強したい人におススメの本は「Google Apps Scriptのツボとコツがゼッタイにわかる本」です。基本的な仕組みから実践まで分かりやすくて、教科書的な本がニガテな人には絶対におススメの本です。








いいなと思ったら応援しよう!