發表文章

Vue(Vue3取代 Vuex?)

圖片
  哎呀,以前在資料管理的部分都被Vuex綁死死,但是在typescript相對來說是很不友善的(我有寫一篇 for vuex在typescript 去定義),自從我用了vue3 的composition API及reactive 就直接使用了 yarn remove vuex ,在typescript的世界裡就是要清清楚楚,簡簡單單,甚麼模板轉換的才不需要呢 我們來創自己管資料的地方吧 type.ts: export interface InterComicsData extends InterGenre { id: string; mainIndex: string; mainIndex_name: string; descr: string; link: string; title: string; thumbnail_name: string; thumbnail_url: string; lastUpdateTime: string; createTime: string; genreDatas: InterGenre[]; } export interface InterGenre { id: string; rootComics_id: string; name: string; } export interface InterComics { comicDatas: InterComicsData[]; genreDatas: InterGenre[]; pageLimit: Number; } comics.ts: 我有做一個漫畫站,這邊是用來管理comics的地方 import Vue, { reactive, defineComponent, readonly } from "vue"; import { InterComicsData, InterComics, InterGenre } from "@/store/comics/type"; import axios from "axios"; import * as data

前端優化效能-1(lazy-img)

圖片
在Chrome底下可以使用在img DOM加入 loading="lazy" 就可以直接使用懶加載了,或者裝線上有的plugin也可以的(但是我喜歡自己來) <img src="image.png" loading="lazy" alt="..." /> 但IE跟Safari是不支援這樣的語法的,所以只好自己幹一個了,我們來用 IntersectionObserver吧(結果IE 也沒支援attribute QAQ) //註冊在讀取圖檔時要做的事情 window.addEventListener('load', () => {      const watcher = new IntersectionObserver(onEnterView) const elementArrary = document.getElementsByClassName('your_imgName'); for (let image of elementArrary) { watcher.observe(image) // 開始監視 } } //IntersectionObserver 的call back function onEnterView(entries: IntersectionObserverEntry[], observer: IntersectionObserver) { for (let entry of entries) { if (entry.isIntersecting) { // Element show on the loadImage(entry.target) // cancel watch observer.unobserve(entry.target) } } } // load img logic function loadImage(img: HTMLImageElement) { const removeMockup = (

Vue那些我踩過的坑(Vuex-TypeScript)

圖片
在var來var去的同時雖然很方便,但也留下了許多技術債,在專案變大的同時未來是需要還的,但是在Vuex裡面使用TypeScript是非常痛苦的,因為VUEX本身的寫法是不支援TypeScript,這邊我示範一下如何重新定義store能夠好好低與typeScript結合吧 Store結構: type,是定義本身型別放置的地方 store │ index.ts │ type.ts │ └───rootComic actions.ts getters.ts index.ts mutation.ts type.ts index.d.ts: 我們可以從index底層Store的code,看到有個模板可以轉換成你想要的物件,裡面的 <S> 就是你定義的型別 export interface StoreOptions<S> { state?: S | (() => S); getters?: GetterTree<S, S>; actions?: ActionTree<S, S>; mutations?: MutationTree<S>; modules?: ModuleTree<S>; plugins?: Plugin<S>[]; strict?: boolean; devtools?: boolean; } Store定義: Step1: 開一個type.ts的檔案宣告我們 <S> 的型別,State本是個放資料的地方,要放資料的地方一定少不了interface,我們就以interface的方式來定義我們的state吧 export interface RootState { "rootmessage": string } Step2: 原本的寫法 import { createStore } from 'vuex' export default createStore({ state: { }, mutations: { }, actions: { }, modules: { } });

Vue那些我踩過的坑(eslint)

圖片
  程式碼有太多風格,程式碼越來越亂嗎?快來使用eslint提升你程式碼的品質 安裝: npm install eslint -g 要點: 1.找出語法錯誤 沒宣告變數就拿來用、少了括號等等常見的語法錯誤 2.讓你使用最佳實踐 不使用全域變數、建議使用 === 而非 ==、不使用 eval … 3. 提醒你刪掉多餘的程式碼 有些變數宣告了卻沒有使用、 import  了沒有使用的模組、空的 class constructor … 4. 統一基本的 coding style 要不要加分號、使用單引號或雙引號、縮排使用 space 或 tab 等等 與git整合: 我們有npm run lint 這個 script,但一定有人忘了跑直接就上code 了,可以配合 pre-commit 先跑  npm install --save-dev pre-commit  安裝他,安裝完之後在  package.json  加上  "pre-commit": ["lint"]  就完成了,整個檔案會長這樣 "name": "...", "scripts": { "lint": "eslint src/*.js" }, "pre-commit": ["lint"], "dependencies": { ... } "devDependenceies": { "pre-commit": "^1.2.2", ... } 那以後當任何人在專案下跑  git commit -m "message …"  就會先觸發 ESLint 檢查程式碼,通過之後才會成功 commit 結語: 在開發的時候常會有人用不嚴謹的方式宣告變數以及寫法,用了eslint可以大大的減少這方面的困擾

爬蟲7-棄坑Scrapy框架(request)

圖片
  在開發到一半的爬蟲突然覺得Scrapy的彈性有點低,所以就立馬轉彎了 Scrapy缺點: 1.在yield資料的時候,只能擇一pipline來做資料的存取,假如我要ftp跟sql跟json只能擇一來做資料的存取 2.本身的功能還有些bug 是你無法去修復的 3.開發的彈性太差,不好擴充功能,必須照著官方檔案來實作 MySpider: 最後決定用最原始的方式來爬蟲,而這是我專案的結構 C:. └───mySpider-Sample │ .gitattributes │ .gitignore │ .gitignore.swp │ chromedriver.exe │ errorRecoder.py │ ftp.py │ main.py │ myfilter.py │ myProxy.py │ mysql.py │ README.md │ requirements.txt │ spider.py │ spider_playwright.py │ └───chromedriver chromedriver.exe 主項: a.spider: 1.主要是request搭配beautifulsoup 2.有存json以及圖片的功能 3.有限制防爬蟲的網站,目前沒有好的解決辦法 b.spider_playwright: 1.以playwright為主體 2.有存json以及圖片的功能 3.模擬器叫起瀏覽器方式 c.mysql: 1.存取sql的方法可以寫在這裡 2.我有寫一個getData的功能,(可以自行擴充喔) 3.擴充sql方法都可以寫在這裡 d.main: 程式的起始點 e.myproxy: 1.爬取免費的proxy  2.經過muyiple threads 驗證過拿的proxy都是活的,品質的話則不一定 f.myfilter: 1.透過跟sql要資料去排除重複性的資料 # here is get sql data to check it's existed it will remove duplicat

爬蟲6-PlayWright(仿真模擬器)

圖片
  前言: 我們來講講 PlayWright ,他是一個微軟開發的瀏覽器模擬器,也可以用來測試網站對於瀏覽器的相容性,他提供了 chrome , firefox , webkit 三個模擬器,之前在使用 seleium 還必須特別下載 driver 然後配置路徑給他,有點不太好用,如果 seleium 跟 playwright 兩個要相比的話,我會說playwright 更好用,更可以直接對 element 給執行 click 的動作,真的擬仿操作網站的行( 未來考慮做一個流量機器人來玩 ) Python 環境安裝: pip install playwright here is install browser emulate playwright install 我把爬蟲最常用的幾個功能列在下面: a.selector的基本用法: 1.以 // 或 / 或者 .. 開頭的,判斷為xpath pp = page.querySelector("xpath=//h2") pp = page.querySelector("//h2") 2.以引號 "" 或者 ' 開頭的,判斷為text ppp = page.querySelector("text=文本輸入") \ ppp = page.querySelector("'文本輸入'") 注意:雙引號里有一個單引號,不然無法識別 3.其他的,都判斷為css p = page.querySelector("css=h2") p = page.querySelector("h2") b.wait_for_selector: 等待你找的element出現後就會繼續往下,沒有則hand住,直到出現為止, #會等待element已經被生成才會往下 page.wait_for_selector('div.thumb-overlay-albums > a') c.query_selector: 如果有重複地class名,則會以找到第一個優先回傳,在尋找class 的時候同一個element無法抓取兩個以上的cla

爬蟲5-Seleium(如何使用)

圖片
  為什麼需要用Seleiun這樣的網站模擬器去叫起一個Browser呢?因為有些資料為了防止爬蟲,如果不是透過瀏覽器的方式叫起,將會無法trigger有拿資料的 function ,這是目前拿隱藏資料最快的解決辦法 裝好套件 pip install selenium 我們必須去載 chromedriver 然後放在我們專案的路徑下就可以使用了 範例: 情境是,某網站的Canvas是被Function 驅動後才產生的,所以直接發Request 返回是找不到Canvas這個節點 from selenium import webdriver from selenium.webdriver.chrome.options import Options options = Options() options.add_argument("--disable-notifications") chrome = webdriver.Chrome('./chromedriver/chromedriver.exe', chrome_options=options) chrome.get(response._url) # check we had canvas to insert data canvas = chrome.find_element_by_xpath("//canvas").size != 0 print(canvas) 透過Seleium叫起瀏覽器就可以去看Canvas 是否有被產生出來 小結: 透過瀏覽器的方式,以爬蟲速度來講是很慢的一件事情,接下來會去尋求更快的方法,如果有新的方法,會在此篇文章更新的