クリックしたボタンのXpathを記録したい。
Xpathで記録したいんだけど、ルートからのXpathって表記が長くって、可読性低い。つまるところメンテナンス性能が最悪。
xpath を検索条件で保存したいですね・
つぎのようなXpathで保存されるとナニが何かわからない。
/html/body/div[4]/div[2]/div/div/div/div[2]/a
だから、次のようなxpathで保存したい
//a[contains(./text(), ' Download ')][@href='#']
ぱぱっと書いてみた。
content_script として突っ込んで、Extensionに、クリックしたリンクやボタンを始め、クリックした要素のXpathを送ることにした。
document.body.addEventListener( "click" , function(e){ console.clear() get_xpath_expression = function(e) { if (e.nodeType == 9) { return ""; } //////////////////////////////////////////////////// // scraping 用なので id より input[]/a[] 表記を優先する。 //////////////////////////////////////////////////// //リンクの場合の処理。 if( /a$/.test(e.tagName.toLowerCase()) ){ str = `//${e.tagName.toLowerCase()}` if (e.text.trim() != "" ) { str += `[contains(./text(), '${e.textContent}')]` } "id href name".split(/\s+/).forEach( function( attr_name ){ if ( e.getAttribute(attr_name)) { str += `[@${attr_name}='${e.getAttribute(attr_name)}']` } }) return str; } //input の処理 if( /input$/.test(e.tagName.toLowerCase()) ){ str = `//${e.tagName.toLowerCase()}` "name type value id".split(/\s+/).forEach( function( attr_name ){ if ( e.getAttribute(attr_name)) { str += `[@${attr_name}='${e.getAttribute(attr_name)}']` } }) return str; } if( /form$/.test(e.tagName.toLowerCase()) ){ str = `//${e.tagName.toLowerCase()}` "name action id".split(/\s+/).forEach( function( attr_name ){ if ( e.getAttribute(attr_name)) { str += `[@${attr_name}='${e.getAttribute(attr_name)}']` } }) return str; } if( /button$/.test(e.tagName.toLowerCase()) ){ str = `//${e.tagName.toLowerCase()}` if (e.text.trim() != "" ) { str += `[contains(./text(), '${e.textContent}')]` } "id name value".split(/\s+/).forEach( function( attr_name ){ if ( e.getAttribute(attr_name)) { str += `[@${attr_name}='${e.getAttribute(attr_name)}']` } }) return str; } // if (e.hasAttribute("id")) { return 'id("' + e.getAttribute("id") + '")' } var p = e.parentNode; var t = get_xpath_expression(p) + "/" + e.tagName.toLowerCase(); var c = p.childNodes; var g = 0; var s; for (var i = 0, n = c.length; i < n; ++i) { if (c[i].nodeName == e.nodeName && c[i].nodeType == e.nodeType) { ++g; if (c[i] == e) { s = g } } } if (g == 1) { return t } t += "[" + (s) + "]"; return t } var xpath_str = get_xpath_expression(e.target) console.log(xpath_str) var message_sample = function(){ var id = "icjaalhedjpokjepgfojceaclllpdman"; data = { xpath: xpath_str, url : window.location.toString(), title : window.document.title, origin : window.location.origin } console.log(data) chrome.runtime.sendMessage(id, data, null , function(x){ console.log("sent"); console.log(x); } ) } message_sample() }, true);
拡張機能にして保存してみた。
クリックを追いかけられるのは便利かもしれない。
ついでに、rubyのSeleniumソースを自動生成するようにしたので、スクレーパーの雛形をぱぱっと作ることが出来て嬉しい。
プロファイルを工夫すれば、請求書の取得をさらに自動化して遊べそう。
フォーム入力値どうするか。
テキスト入力は日本語があるから、シンドいんですよね。
onchage イベントでも監視しよう。
こっちはそのうちやる。