- // ==UserScript==
- // @name 排名查询
- // @namespace http://blog.sxnxcy.com/
- // @version 1.0.1
- // @description 搜索引擎排名查询
- // @author xiaobao
- // @license CC-BY-4.0
- // @run-at document-start
- // @grant GM_addStyle
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_getResourceURL
- // @grant GM_openInTab
- // @grant GM_xmlhttpRequest
- // @grant GM_notification
- // @match *://*.baidu.com/*
- // @match *://*so.toutiao.com/*
- // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js
- // @require https://unpkg.com/layui@2.8.6/dist/layui.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.core.min.js
-
- // ==/UserScript==
-
- (function () {
- console.log("脚本注入成功", GM_info.script.version);
- GM_addStyle(`@import url('https://unpkg.com/layui@2.8.6/dist/css/layui.css');
- .chrome-plugin-demo-panel {
- position: fixed;
- right: 0;
- bottom: 10px;
- padding: 10px;
- width: 500px;
- height: 800px;
- margin-right: 30px;
- }
- #pzdv{
- position: fixed;
- right: 0;
- bottom: 30px;
- padding: 40px;
- margin-right: 40px;
- }
- `);
- })();
- let nbHtml = `
- <div class="layui-field-box">
- <div class="layui-row layui-col-space5">
- <div class="layui-col-xs4">
- <input type="text" id="ys" placeholder="搜索页数" class="layui-input" value="1">
- </div>
- <div class="layui-col-xs4">
- <input type="text" id="sl" placeholder="每页数量" class="layui-input" value="50">
- </div>
- </div>
- <div class="layui-row">
- <div class="layui-col-xs12">
- <textarea id="gjc" placeholder="请输入关键词" class="layui-textarea"
- style="height: 200px;">九方智投 site:www.9fzt.com</textarea>
- </div>
- <div class="layui-col-xs12">
- <textarea id="ym" placeholder="域名或者链接" class="layui-textarea"
- style="height: 200px;">www.9fzt.com</textarea>
- </div>
- </div>
- <div class="layui-row">
- <hr>
- <div class="layui-progress layui-progress-big" lay-showPercent="true" lay-filter="demo-filter-progress">
- <div id="jdt" class="layui-progress-bar" lay-percent="0%">
- </div>
- </div>
- </div>
- <div class="layui-row layui-col-space5">
- <hr>
- <button id="saveStart" class="layui-btn layui-btn-primary layui-border-blue">开始</button>
- <button id="butTest" class="layui-btn layui-btn-primary layui-border-red">下载结果</button>
- <div class="layui-form">
- <input id="checkbox1" type="checkbox" name="" title="只取一条">
- </div>
- </div>
- </div>
- `;
- let zjg = []
- let zarr = []
- document.addEventListener('DOMContentLoaded', function () {
- insertPage();
- localStorage.yzm = 1
- $("#pzan").click(function () {
- layer.open({
- type: 1,
- title: "排名查询配置",
- offset: 'auto',
- anim: 'slideLeft', // 从右往左
- area: ['750px', '50%'],
- shade: 0.1,
- shadeClose: false,
- id: 'ID-demo-layer-direction-r',
- content: nbHtml
- });
- layui.use('form', function () {
- var form = layui.form;
- form.render()
- });
- configurationButtonEvent()
- });
- })
- function sendMessage(title, message) {
- GM_notification({
- text: message,
- title: title,
- timeout: 5000, // 通知显示时间,单位为毫秒,默认为 4000 毫秒
- onclick: function () {
- }
- });
- }
- // 配置按钮事件
- function configurationButtonEvent() {
- $("#saveStart").click(() => {
- setTimeout(function () {
- rw($("#gjc").val(), $("#ym").val())
- }, 500)
- })
- $("#butTest").click(function () {
- xz();
- });
- }
- // 进度条更新
- function jdtup(bfb) {
- layui.element.progress('demo-filter-progress', bfb + "%")
- document.querySelector("#jdt").innerText = bfb + "%"
- }
- //插入配置按钮页
- function insertPage() {
- var panel = document.createElement('div');
- panel.id = 'pzdv';
- let html = `<button id="pzan" type="button" class="layui-btn layui-btn-primary" lay-on="test-offset-r"></button>`
- panel.innerHTML = html
- document.body.appendChild(panel);
- document.querySelector("#pzan").innerText = "排名查询 当前版本:" + GM_info.script.version
- }
- // 任务处理
- async function rw(gjc, ym) {
- zjg = []
- zarr = [["关键词", "排名", "域名", "真实地址", "标题"]]
- sendMessage('排名查询', '任务开始');
- jdtup(0)
- let ys = Number(document.querySelector("#ys").value)
- let sl = Number(document.querySelector("#sl").value)
- let gjcsz = gjc.trim().split("\n")
- let ymsz = ym.trim().split("\n")
- if (gjcsz.length != ymsz.length) {
- sendMessage('排名查询', '关键词域名数量不对应任务结束');
- return
- }
- for (let index = 0; index < gjcsz.length; index++) {
- console.log("当前执行:" + gjcsz[index]);
- await singleTaskProcessing(gjcsz[index], ymsz[index], ys, sl)
- jdtup(Math.floor((index + 1) / gjcsz.length * 100))
- await delayedAction()
- }
- sendMessage('排名查询', '任务完成');
- console.log("结果预览:", zjg);
- }
-
- // 单任务处理
- async function singleTaskProcessing(gjc, ym, ys, sl) {
- switch (location.host) {
- case "www.baidu.com":
- baiduPc(gjc, ym, ys, sl)
- break;
- case "m.baidu.com":
- baiduYd(gjc, ym, ys, sl)
- break;
- case "so.toutiao.com":
- touduPc(gjc, ym, ys, sl)
- break;
- default:
- break;
- }
- }
-
- async function baiduPc(gjc, ym, ys, sl) {
- let dt = document.getElementById('checkbox1').checked
- for (let index = 0; index < ys; index++) {
- url = "https://www.baidu.com/s?wd=" + encodeURIComponent(gjc) + "&pn=" + index * sl + "&rn=" + sl
- let str = await syncGet2(url) //json接口匹配
- let parser = new DOMParser();
- let doc = parser.parseFromString(str, 'text/html');
- let bqsz = doc.querySelectorAll("#content_left [srcid]");
- for (let bq of bqsz) {
- if (bq.querySelector("H3") != null) {
- let dz = bq.getAttribute("mu")
- let pm = bq.getAttribute("id")
- let bt = bq.querySelector("H3").innerText
- if (getDomain(dz, ym)) {
- zarr.push([gjc, pm, ym, dz, bt])
- zjg.push([gjc, pm, ym, dz, bt])
- if (dt) {
- return //取单条返回
- }
- }
- }
- }
- }
- }
- async function baiduYd(gjc, ym, ys, sl) {
- let dt = document.getElementById('checkbox1').checked
- for (let index = 0; index < ys; index++) {
- url = "https://m.baidu.com/s?word=" + encodeURIComponent(gjc) + "&pn=" + index * sl
- let str = await syncGet2(url) //json接口匹配
- let parser = new DOMParser();
- let doc = parser.parseFromString(str, 'text/html');
- let bqsz = doc.querySelectorAll(".c-result.result");
- for (let bq of bqsz) {
- if (bq.querySelector("H3") != null) {
- let xjson = JSON.parse(bq.getAttribute("data-log"))
- let dz = xjson.mu
- let pm = xjson.order + index * 10
- let bt = bq.querySelector("H3").innerText
- if (getDomain(dz, ym)) {
- zarr.push([gjc, pm, ym, dz, bt])
- zjg.push([gjc, pm, ym, dz, bt])
- if (dt) {
- return //取单条返回
- }
- }
- }
- }
- }
- }
-
- async function touduPc(gjc, ym, ys, sl) {
- let dt = document.getElementById('checkbox1').checked
- for (let index = 0; index < ys; index++) {
- url = "https://so.toutiao.com/search?dvpf=pc&source=pagination&keyword=" + encodeURIComponent(gjc) + "&page_num=" + (index)
- let str = await syncGet2(url) //json接口匹配
- let parser = new DOMParser();
- let doc = parser.parseFromString(str, 'text/html');
- let bqsz = doc.querySelectorAll("div.s-result-list div.result-content[data-i]");
- for (let bq of bqsz) {
- if (bq.querySelector("[data-log-extra]") != null) {
- let xjson = JSON.parse(bq.querySelector("[data-log-extra]").getAttribute("data-log-extra"))
- let dz = ""
- console.log(bq.querySelector("[data-log-extra]").getAttribute("data-log-extra"));
- if (xjson.hasOwnProperty("url")) {
- dz = xjson.url
- } else {
- if (xjson.result_type == "self_video") {
- dz = "https://www.toutiao.com/video/" + xjson.search_result_id + "/?channel=&source=search_tab"
- }
- if (xjson.result_type == "self_article") {
- dz = "https://www.toutiao.com/article/" + xjson.search_result_id + "/?channel=&source=search_tab"
- }
- if (xjson.result_type == "user") {
- dz = xjson.common_params.items[0].doc_url
- }
-
- }
- let pm = Number(bq.getAttribute("data-i")) * (index + 1) + 1
- let bt = bq.querySelector("a").innerText
- if (getDomain(dz, ym)) {
- zarr.push([gjc, pm, ym, dz, bt])
- zjg.push([gjc, pm, ym, dz, bt])
- if (dt) {
- return //取单条返回
- }
- }
- }
- }
- }
- }
- // 延迟
- function sleep(ms) {
- return new Promise((resolve) => {
- setTimeout(resolve, ms);
- });
- }
- //延迟执行
- async function delayedAction(s) {
- if (s == null | s == undefined) {
- s = 1000
- }
- await sleep(s);
- }
- async function xz() {
- const wb = XLSX.utils.book_new();
- const ws = XLSX.utils.aoa_to_sheet(zarr);
- XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
- const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });
- const blob = new Blob([wbout], { type: 'application/octet-stream' });
- const downloadLink = document.createElement('a');
- downloadLink.id = "downloadLink"
- downloadLink.href = URL.createObjectURL(blob);
- downloadLink.download = 'data.xlsx';
- downloadLink.click();
- downloadLink.remove()
- }
- async function syncGet2(url) {
- let xhr = null
- while (true) {
- if (localStorage.yzm == "1") {
- xhr = new XMLHttpRequest();
- xhr.open('GET', url, false); // 同步请求
- xhr.send();
- }
- if (localStorage.yzm == "1" && xhr && (xhr.responseURL.indexOf("wappass.baidu.com") > -1)) {
- localStorage.yzm = "0"
- sendMessage("百度搜索", "请手动处理验证码")
- window.open(xhr.responseURL)
- } else { //ok
- if (xhr && xhr.responseURL.indexOf("wappass.baidu.com") == -1) {
- return xhr.responseText
- }
- }
- if (localStorage.yzm == "0") {
- console.log("等待验证码处理中...");
- await delayedAction(10000)
- debugger
- }
- }
- }
-
-
- // 链接对比模糊对比
- function getDomain(url, url2) {
- url = url.replaceAll("http://", "").replaceAll("https://", "")
- url2 = url2.replaceAll("http://", "").replaceAll("https://", "")
- return url.indexOf(url2) > -1
- }