使用node搭建自動(dòng)發(fā)圖文微博機(jī)器人的方法
本文僅供學(xué)習(xí)交流,請(qǐng)勿用于商業(yè)用途,并遵守新浪微博相關(guān)規(guī)定。
代碼目錄
此微博機(jī)器人的實(shí)現(xiàn)功能如下:
- 模擬登陸新浪微博,獲取cookie;
- 自動(dòng)上傳圖片至微博圖床;
- 自動(dòng)發(fā)送內(nèi)容不同的圖文微博;
- 通過(guò)定時(shí)任務(wù),實(shí)現(xiàn)周期性發(fā)微博任務(wù)。
效果圖
圖文內(nèi)容我固定了,可自行使用第三方api獲取要發(fā)送的內(nèi)容或爬取第三方內(nèi)容發(fā)送。(偷個(gè)懶...
要實(shí)現(xiàn)發(fā)送圖文微博可以分為三個(gè)步驟
- 登錄微博。
- 圖片上傳至微博圖床獲取PID。
- 發(fā)送微博。
登錄
登錄可以使用Puppeteer node庫(kù),很輕松的實(shí)現(xiàn)登錄獲取微博cookie,這里不多介紹,可以自行搜索Puppeteer學(xué)習(xí)。
Puppeteer是谷歌官方出品的一個(gè)通過(guò)DevTools協(xié)議控制headless Chrome的Node庫(kù)。可以通過(guò)Puppeteer的提供的api直接控制Chrome模擬大部分用戶操作來(lái)進(jìn)行UI Test或者作為爬蟲訪問(wèn)頁(yè)面來(lái)收集數(shù)據(jù)。
async function login(username, password) { const browser = await puppeteer.launch({ // headless: false, slowMo: 250, executablePath: '' }); const page = (await browser.pages())[0]; await page.setViewport({ width: 1280, height: 800 }); await page.goto("https://weibo.com/"); await page.waitForNavigation(); await page.type("#loginname", username); await page.type("#pl_login_form > div > div:nth-child(3) > div.info_list.password > div > input", password); await page.click("#pl_login_form > div > div:nth-child(3) > div:nth-child(6)"); await page.waitForNavigation().then(result => { return new Promise((resolve) => { page.cookies().then(async cookie => { fs.createWriteStream("cookie.txt").write(JSON.stringify(cookie), "UTF8");//存儲(chǔ)cookie await browser.close();//關(guān)閉打開的瀏覽器 resolve(cookie); }); }) }).catch(e => { page.screenshot({ path: 'code.png', type: 'png', x: 800, y: 200, width: 100, height: 100 }); return new Promise((resolve, reject) => { readSyncByRl("請(qǐng)輸入驗(yàn)證碼").then(async (code) => { await page.type("#pl_login_form > div > div:nth-child(3) > div.info_list.verify.clearfix > div > input", code); await page.click("#pl_login_form > div > div:nth-child(3) > div:nth-child(6)"); await page.waitForNavigation(); page.cookies().then(async cookie => { fs.createWriteStream("cookie.txt").write(JSON.stringify(cookie), "UTF8"); await browser.close(); resolve(cookie); }); }) }) }) }
圖片上傳至微博圖床
上傳到微博圖床可以看這里 http://weibo.com/minipublish 抓包看上傳的接口過(guò)程,可以看到上傳的是base64圖片信息。所以上傳前把圖片轉(zhuǎn)換成base64編碼,而本地圖片的編碼和互聯(lián)網(wǎng)鏈接圖片的編碼又不一樣,這里使用的是互聯(lián)網(wǎng)鏈接的圖片,node本地圖片轉(zhuǎn)換成base64編碼更簡(jiǎn)單些。上傳成功后返回微博圖床圖片的pid。記住這個(gè)pid,發(fā)微博用的就是這個(gè)pid。
發(fā)送微博
有了微博cookie和圖片pid后就可以發(fā)微博了,多張圖片時(shí)pid之間以|隔開的。
async function weibopost(text, pic_ids = '', cookie) { //發(fā)送微博內(nèi)容(支持帶圖片) return new Promise(async (resolve, reject) => { if (cookie === '') { reject('Error: Cookie not set!'); } let post_data = querystring.stringify({ 'location': 'v6_content_home', 'text': text, 'appkey': '', 'style_type': '1', 'pic_id': pic_ids, 'tid': '', 'pdetail': '', 'mid': '', 'isReEdit': 'false', 'rank': '0', 'rankid': '', 'module': 'stissue', 'pub_source': 'main_', 'pub_type': 'dialog', 'isPri': '0', '_t': '0' }); let post_options = { 'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7', 'Connection': 'keep-alive', 'Content-Length': Buffer.byteLength(post_data), 'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': cookie, 'Host': 'weibo.com', 'Origin': 'https://weibo.com', 'Referer': 'https://weibo.com', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest' }; let { data } = await axios.post('https://weibo.com/aj/mblog/add?ajwvr=6&__rnd=' + new Date().getTime(), post_data, { withCredentials: true, headers: post_options }) if (data.code == 100000) { console.log('\n' + text + '-----Sent!' + '---' + new Date().toLocaleString()); resolve(data); } else { console.log('post error'); reject('post error'); } }); }
最后就是定時(shí)任務(wù)了,定時(shí)任務(wù)可以使用node-schedule node庫(kù),這里不多介紹,可以自行搜索學(xué)習(xí)。這里使用的是每隔10分鐘發(fā)送一次。
function loginTo() { login(config.username, config.password).then(async () => { let rule = null; rule = new schedule.RecurrenceRule(); rule.minute = [01, 11, 21, 31, 41, 51]; try { let cookie = await getCookie(); getContent(cookie); } catch (error) { console.log(error); } j = schedule.scheduleJob(rule, async () => { //定時(shí)任務(wù) try { let cookie = await getCookie(); getContent(cookie); } catch (error) { console.log(error); } }); }) }
代碼地址: github地址
參考
https://github.com/itibbers/weibo-post
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Node.js里面的內(nèi)置模塊和自定義模塊的實(shí)現(xiàn)
這篇文章主要介紹了Node.js里面的內(nèi)置模塊和自定義模塊的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05Nodejs+express+html5 實(shí)現(xiàn)拖拽上傳
文件上傳是一個(gè)比較常見的功能,傳統(tǒng)的選擇方式的上傳比較麻煩,需要先點(diǎn)擊上傳按鈕,然后再找到文件的路徑,然后上傳。給用戶體驗(yàn)帶來(lái)很大問(wèn)題。html5開始支持拖拽上傳的需要的api。nodejs也是一個(gè)最近越來(lái)越流行的技術(shù),這也是自己第一次接觸nodejs。2014-08-08node.js解決獲取圖片真實(shí)文件類型的問(wèn)題
這篇文章主要介紹了node.js解決獲取圖片真實(shí)文件類型的問(wèn)題,本文根據(jù)二進(jìn)制流及文件頭獲取文件類型mime-type,然后讀取文件二進(jìn)制的頭信息,獲取其真實(shí)的文件類型,需要的朋友可以參考下2014-12-12node.js中的fs.fchmod方法使用說(shuō)明
這篇文章主要介紹了node.js中的fs.fchmod方法使用說(shuō)明,本文介紹了fs.fchmod的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12nodejs中簡(jiǎn)單實(shí)現(xiàn)Javascript Promise機(jī)制的實(shí)例
這篇文章主要介紹了nodejs中簡(jiǎn)單實(shí)現(xiàn)Javascript Promise機(jī)制的實(shí)例,本文在nodejs中簡(jiǎn)單實(shí)現(xiàn)一個(gè)promise/A 規(guī)范,需要的朋友可以參考下2014-12-12node+koa2+mysql+bootstrap搭建一個(gè)前端論壇
本篇文章通過(guò)實(shí)例給大家分享了用node+koa2+mysql+bootstrap搭建一個(gè)前端論壇的步驟,有需要的朋友參考下。2018-05-05Node.js折騰記一:讀指定文件夾,輸出該文件夾的文件樹詳解
這篇文章主要介紹了Node.js讀指定文件夾輸出該文件夾文件樹,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04