Puppeteer[edit]

Error: Node is either not visible or not an HTMLElement[edit]

単に、指定したセレクタが複数あるだけかも。例えばinput[name="password"]が2つあるときに、await page.typeやawait page.focusなどは上記エラーが出る(ことがある)。そういうときはclass: ElementHandleでオブジェクトのリストを取得し、リストの番号で目的のオブジェクトを操作すればよい。例えば2つ目を扱いたいなら、

let items = await page.$$('input[name="password"]');
items[1].click();

pageクラスと書式が同じものもあれば違うものもある。例えばelementHandle.typeは、セレクタを引数に取らない。puppeteer/api.md at master · GoogleChrome/puppeteer · GitHub

sample[edit]

新電力 あしたでんき[edit]

スマートメーターの情報をグラフで表示するページを電力各社は提供している。私が契約している「あしたでんき」は、データをCSV等でダウンロードできないので、画面から取得している。当初、Greasemonkeyで試したが失敗したので、Puppeteerに切り替えた。

このサンプルでは、前月のデータをTSVで書き出している。当月を取得したいなら前月に移動するコードを削除すればよい。

const puppeteer = require('puppeteer');
const fs = require('fs');
const cheerio = require('cheerio');
const path = require('path');

let tsvfile = path.join(__dirname, 'ashitadenki.tsv');

(async() => {
	const browser = await puppeteer.launch({
		headless: false,
		args: [
			'--no-sandbox',
		]
	});
	const page = await browser.newPage();
	await page.setViewport({width: 1024, height: 2048});
try {

	await page.goto('https://ashita-denki.jp/login/', { waitUntil: 'networkidle2'});
	await page.waitForSelector('input#username', {waitUntil: 'networkidle2', timeout: 10000});
	await page.focus("input#username");
	await page.type("input#username", 'your ID');
	await page.focus("input#password");
	await page.type("input#password", 'your password');
	await page.waitFor(1000);
	await page.click('input[type=submit]');
	await page.waitForNavigation({waitUntil: 'load'});

	await page.waitForSelector('#monthly-report-table', {waitUntil: 'networkidle2', timeout: 2500});


	var now   = new Date();
	var month = now.getMonth(); //1月は0

	// 前の月を表示する
	await page.waitForSelector('#month > form > div:nth-child(1) > select:nth-child(2)');
	await page.select('#month > form > div:nth-child(1) > select:nth-child(2)', month.toFixed());
	await page.waitFor(3000);

	await page.waitForSelector('#monthly-report-table', {waitUntil: 'networkidle2', timeout: 2500});


	let html = await page.$eval('#monthly-report-table > ul', e => e.outerHTML);
	$ = cheerio.load(html);

	let lines = [];
	$('li').each(function(){
		let row = [];

		// #monthly-report-table > ul > li:nth-child(1) > time
		row.date = $(this).find('time').text().trim();
		if (row.date == '') {
			return true; //$().eachのnext
		}
		row.date = row.date.replace(/日/,'');
		row.date = month.toFixed() + '/' + row.date;

		// #monthly-report-table > ul > li:nth-child(1) > ul > li.kwh > span
		row.kw = $(this).find('ul > li.kwh > span').text().trim();
		// #monthly-report-table > ul > li:nth-child(1) > ul > li.cost > span
		row.cost = $(this).find('ul > li.cost > span').text().trim();

		lines.push(Object.values(row).join("\t"));
	});

	fs.writeFile(tsvfile, lines.join("\n"),(err) => {
		if (err) throw err;
	});

} catch (e) {
	console.log('caught');
	process.stderr.write(e.toString());
	await browser.close();
	process.exit(1);
}

	await browser.close();
})();

Node.js[edit]

cheerio[edit]

文字コード[edit]

Perl[edit]

メモ[edit]


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-31 (土) 15:20:05