Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
習目的:對檢索的內容進行模糊匹配,學習使用正則表達式進行搜索。
學習內容:WHERE字句的REGEXP字句。
SELECT [column_name] FROM [table_name] WHERE [column_name] REGEXP '正則表達式';
--正則表達式的寫法需要另外學習,且MySQL支持的正則表達式也只是其子集。
拓展內容:
--正則表達式是用來匹配文本的特殊的串(字符集合)。如果你想從一個文本文件中提取電話號碼,可以使用正則表達式。如果你需要查找名字中間有數字的所有文件,可以使用如果你想替換一個頁面中的所有URL為這些URL的實際HTML鏈接,也可以使用一個正則表達式所有種類的程序設計語言、文本編輯器、操作系統等都支持正則表達式。
--LIKE匹配整個列。如果被匹配的文本在列值中出現,LIKE將不會找到它,相應的行也不被返回(除非使用通配符)。而REGEXP在列值內進行匹配,如果被匹配的文本在列值中出現,REGEXP將會找到它,相應的行將被返回。這是一個非常重要的差別。那么,REGEXP能不能用來匹配整個列值(從而起與LIKE相同的作用)?答案是肯定的,使用^和$定位符(anchor)即可。
者 | 不愿透露姓名の網友
出品 | CSDN博客
介紹爬蟲
1.爬蟲:自動的抓取互聯網上信息的腳本文件。
2.爬蟲可以解決的問題:
(1)解決冷啟動問題
(2)搜索引擎的根基:做搜索引擎少不了爬蟲
(3)建立知識圖譜,幫助建立機器學習知識圖譜
(4)可以制作各種商品的比價軟件,趨勢分析。
3.爬蟲分類
(1)通用爬蟲:搜索引擎的主要組成,作用就是將互聯網的上頁面整體的爬取下來之后,保存到本地。
(2)聚焦爬蟲:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,盡量保證只抓取與需求相關的網頁信息。
通用爬蟲和聚焦爬蟲的區別:聚焦爬蟲在實施網頁抓取時會對內容進行處理篩選,盡量保證只抓取與需求相關的網頁信息。
4.爬蟲遵循的協議:robot協議
定義:網絡爬蟲排除標準。
作用:告訴搜索引擎哪里可以爬,哪里不可以爬。
5.通用爬蟲工作流程
(1)抓取網頁:通過搜索引擎將待爬取的url加入到通用爬蟲的url隊列中,進行網頁內容的爬取
(2)數據存儲:將爬取下來的網頁保存到本地,這個過程會有一定的去重操作,如果某個網頁的內 容大部分內容都會重復,搜索引擎可能不會保存。
(3)預處理:提取文字,中文分詞,消除噪音(比如版權聲明文字,導航條,廣告等)。
(4)設置網站排名,為用戶提供服務。
6.一些反爬及其應對措施
( 1)通過user-agent來判斷是否是爬蟲。
解決方案:可以通過偽裝請求頭中的user-agent來解決。若user-agent被檢測到,可以找大量的user-agent,放入列表,然后進行更換
(2)將IP進行封殺。
解決方案:可以通過代理來偽裝IP。
(3)通過訪問頻率來判斷是否是一個爬蟲。
解決方案:可以通過設置請求間隔,和爬取間隔。
(4)當一定時間內的總請求數超過上限,彈出驗證碼。
解決方案:對于簡單的驗證碼圖片可以使用tesseract來處理,對于復雜的可以去打碼平臺。
(5)通過JS來獲取頁面數據。
解決方案:可以使用selenium+phantomjs來加載JS獲取數據。
介紹搜索引擎
1.搜索引擎的主要組成
通用爬蟲:就是將互聯網的上頁面整體的爬取下來之后,保存到本地。
通用爬蟲要想爬取網頁,需要網站的url.但是搜索引擎是可以搜索所有網頁的。那么通用爬蟲url就要涉及到所有網頁,這個‘所有’是如何做到的:
新網站向搜索引擎主動提交網址;
在其他網站上設置新網站外鏈;
搜索引擎和DNS解析服務商(如DNSPod等)合作,新網站域名將被迅速抓取。
2.搜索引擎的工作流程(通用爬蟲的工作流程)
(1)抓取網頁:通過搜索引擎將待爬取的URL加入到通用爬蟲的URL隊列中,進行網頁內容的爬取。
(2)數據存儲:將爬取下來的網頁保存到本地,這個過程會有一定的去重操作,如果某個網頁的內 容大部分內容都會重復,搜索引擎可能不會保存。
(3)預處理:提取文字,中文分詞,消除噪音(比如版權聲明文字,導航條,廣告等)。
(4)設置網站排名,為用戶提供服務。
3.搜索引擎的局限性
(1)搜索引擎只能爬取原網頁,但是頁面90%內容都是無用的。
(2)搜索引擎不能滿足不同行業,不同人的特定需求。
(3)通用搜索引擎只能爬取文字信息,不能對音頻、圖片等進行爬取。
(4)只能基于關鍵字查詢,無法基于語義查詢。
介紹HTTP
網絡七層協議:
1.HTTP協議特點
HTTP協議是超文本傳輸協議;
HTTP協議是一個應用層協議;
無連接:每次請求都是獨立的;
無狀態,表示客戶端每次請求都不能記錄請求狀態,就是兩條請求直接不可通信。
2.HTTP工作過程
地址進行DNS解析,將URL解析出對應的內容
封裝HTTP請求數據包
封裝成TCP包,建立TCP連接(TCP的三次握手)
客戶端發送請求
服務器接收請求,發送響應
客戶端接收到響應,進行頁面渲染
服務器關閉TCP連接(TCP的四次揮手)
3.HTTP協議和HTTPS協議的區別
HTTP協議是使用明文數據傳輸的網絡協議,明文傳輸會讓用戶存在一個非常大的安全隱患。端口80
HTTPS協議可以理解為HTTP協議的安全升級版,就是在HTTP的基礎上增加了數據加密。端口443
HTTPS協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網絡協議要比HTTP協議安全。
4.HTTP通信
HTTP通信由兩部分組成:客戶端請求消息與服務器響應消息。
5.關于響應常見的響應碼
6.客戶端請求(Get和Post區別)
(1)組成:請求行、請求頭部、空行、請求數據四個部分組成
(2)請求方法Get/Post
(3)Get和Post的區別
GET和POST本質上就是TCP鏈接,并無差別。但是由于HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同。
(4)常見的請求頭
User-Agent:客戶端請求標識。
Accept:傳輸文件類型。
Referer :請求來源。
cookie (cookie):在做登錄的時候需要封裝這個頭。
Content-Type (POST數據類型)
7.服務器響應
(1)組成:狀態行,響應頭,空行,響應正文。
(2)常見的響應頭
Content-Type:text/html;資源文件的類型,還有字符編碼
Content-Length:響應長度
Content-Size響應大小
Content-Encoding告訴客戶端,服務端發送的資源是采用什么編碼的。
Connection:keep-alive這個字段作為回應客戶端的Connection:keep-alive,告訴客戶端服務器的tcp連接也是一個長連接,客戶端可以繼續使用這個TCP連接發送HTTP請求
url
統一資源定位符:
基本格式:scheme://host[:port#]/path/…/?query-string
協議://服務器ip地址:端口號/資源路徑/?key1=參數1&key2=參數2
scheme:協議(例如:HTTP、HTTPS、FTP)
host/IP:服務器的IP地址或者域名
port:服務器的端口(如果是走協議默認端口,缺省端口80),用來從互聯網進入電腦
path:訪問資源的路徑,就是為了在電腦中找到對應的資源路徑
query-string:參數,發送給http服務器的數據
anchor:錨(跳轉到網頁的指定錨點位置)
Q:當我們在瀏覽器輸入一個URL,為什么可以加載出一個頁面?為什么抓包的過程中請求一個URL,出現很多的資源請求?
當我們在瀏覽器輸入一個URL,客戶端會發送這個URL對應的一個請求到服務器獲取內容。服務器收到這個請求,解析出對應內容,之后將內容封裝到響應里發送到客戶端
當客戶端拿到這個HTML頁面,會查看這個頁面中是否有CSS、JS、image等URL,如果有,在分別進行請求,獲取到這些資源。
客戶端會通過HTML的語法,將獲取到的所有內容完美的顯示出來。
Cookie和Session
產生原因:由于HTTP是一個無狀態的協議,每次請求如果需要之前的一些信息,無法記錄,因此為了解決這個問題,產生了一種記錄狀態技術,Cookie和Session。
Cookie指某些網站為了辨別用戶身份,進行會話跟蹤而存儲在用戶本地終端上的數據,種類有會話Cookie和持久Cookie。
(1)會話Cookie指存在瀏覽器內存的Cookie,當瀏覽器關閉,會話Cookie會失效;
(2)持久Cookie是保存在硬盤上的Cookie。
Session用來存儲特定的用戶會話所需的屬性及其配置信息。
Cookie是在客戶端記錄狀態,Session是在服務端記錄狀態。
聯系:當客戶端發送一個Cookie,服務器會從這個Cookie中找到sessionID,再查找出相應的Session信息返回給客戶端,來進行用戶頁面的流轉。如果通過sessionID來查找Session的時候,發現沒有Session(一般第一次登陸或者清空了瀏覽器),那么就會創建一個Session。
hashlib密碼加密
def get_hex(value):
md5_=hashlib.md5
md5_.update(value.encode('utf-8'))
return md5_.hexdigest
關于response.text亂碼問題
response的常用屬性:
1.獲取字符串類型的響應正文:response.text
2.獲取bytes類型的響應正文:response.content
3.響應正文字符串編碼:response.encoding
4.狀態碼:response.status_code
5.響應頭:response.headers
response.text亂碼問題:
#方法一:轉換成utf-8格式
response.encoding='utf-8'
print(response.text)
#方法二:解碼為utf-8 :
with open('index.html','w',encoding='utf-8') as fp: fp.write(response.content.decode('utf-8'))
代理
代理的作用:
1、突破自身IP 訪問限制, 訪問一些平時不能訪問的站點。
2、訪問一些單位或團體內部資源:比如使用教育網內地址段免費代理服務器, 就可以用于對教育網開放的各類FTP 下載上傳, 以及各類資料查詢共享等服務。
3、提高訪問速度:通常代理服務器都設置一個較大的硬盤緩沖區,當有外界的信息通過時, 同時也將其保存到緩沖區中,當其他用戶再訪問相同的信息時,則直接由緩沖區中取屮信息傳給用戶,以提高訪問速度。
4、隱藏真實IP :上網者也可以通過這種方法隱藏自己的IP , 免受攻擊。對于爬蟲來說, 我們用代理就是為了隱藏自身IP , 防止自身的被封鎖。
代理根據匿名程度的分類:
JSON數據
數據的分類:
JSON的本質:是一個字符串,JSON是對JS對象的字符串表達式,它使用文本形式表示一個JS對象的信息。
JSON使用:
(1)json.dumps(Python的list或者dict),將Python的list或者dict返回為一個JSON字符串;
(2)json.loads(json字符串),將JSON字符串返回為Python的list或者dict;
(3)json.dump(list/dict,fp),將Python的list或者dict轉為一個JSON字符串,保存到文件中;
(4)json.load(fp) ,從JSON文件中讀出JSON數據,并轉換為Python的list或者dict。
正則表達式
1、貪婪和非貪婪
(1)正則默認是貪婪模式,所以數量控制符默認是取最大值,也是貪婪。例如*
(2)非貪婪是用?來控制,盡量匹配最少的次數,0次或一次。
2、Python使用格式:
pattern=re.compile('正則表達式')
print(pattern.match(字符串,start,end))#默認從頭開始匹配,只匹配一次,返回一個match對象
print(pattern.search(字符串,start,end))#從任意位置開始匹配,只匹配一次,返回一個match對象
print(pattern.findall(字符串,start,end))#全文多次匹配,將匹配到的結果放到一個list返回給我們
print(pattern.finditer(字符串,start,end))#全文多次匹配,將匹配到的結果放到一個match對象的迭代器返回
3、常見的正則題目
XML
XML的基本知識:
1.定義:XML稱為可拓展性標記語言,類似 HTML;
2.特點:XML具有自描述特性,是一種半結構化數據;
3.作用:XML的設計宗旨是傳輸數據,而非顯示數據??梢宰鳛榕渲梦募褂脕碛涗浺恍┲匾畔?;
4.XML的標簽需要我們自行定義。
HTML和XML 區別:
語法方面:
在HTML中不區分大小寫,在XML中嚴格區分大小寫
在HTML中,在某些情況可以省略閉合標簽。在XML中,絕對不能省略任何標記。
在XML中,單標簽結尾處需要加’/’。
XML文檔中,空白部分不會被解析器自動刪除,但是HTML是過濾掉空格的
在XML中,屬性值必須封裝在引號中。在HTML中,引號可用可不用。
在HTML中屬性名可以不帶屬性值,XML必須帶屬性值而且不能為空。
標記不同:
HTML使用固有的標記,XML沒有固有標記。
作用不同:
XML主要用來傳輸數據,HTML主要用來顯示數據。
Selenium+PhantomJS
Selenium:Web自動測試工具。
PantomJS:是一個無界面的瀏覽器,所以他可以運行JS代碼,幫我們拿到頁面數據。
特點:功能強大,幾乎可以對付任何網頁,但會導致代碼效率低。
Selenium 是一個 Web 的自動化測試工具,可以根據我們的指令,讓瀏覽器自動加載頁面,獲取需要的數據,甚至頁面截屏,或者判斷網站上某些動作是否發生。Selenium 自己不帶瀏覽器,不支持瀏覽器的功能,它需要與第三方瀏覽器結合在一起才能使用。但是我們有時候需要讓它內嵌在代碼中運行, 所以我們可以用一個PhantomJS 的工具代替真實的瀏覽器。Selenium 庫里有個叫 WebDriver 的 API。WebDriver 有點兒像可以加載網站的瀏覽器,但是它也可以查找頁面元素,與頁面上的元 素進行交互 (發送文本、點擊等),以及執行其他動作來運行網絡爬蟲。
PhantomJS 是一個基于 Webkit 的“無界面”瀏覽器,它會把網站加載到內存并執行頁面上的 JavaScript,因為不會展示圖形界面,所以運行起來比完整的瀏覽器要高效。相比傳統的 Chrome或 Firefox 瀏覽器等,資源消耗會更少。如果我們把 Selenium 和 PhantomJS 結合在一起,就可以運行一個非常強大的網絡爬蟲了,這個爬蟲可以處理 JavaScript、Cookie、headers,以及任 何我們真實用戶需要做的事情。主程序退出后,selenium 不保證 phantomJS 也成功退出,最好手動關閉 phantomJS 進程。(有可能會導致多個 phantomJS 進程運行,占用內存)。WebDriverWait 雖然可能會減少延時,但是目前存在 bug(各種報錯),這種 情況可以采用 sleep。phantomJS 爬數據比較慢,可以選擇多線程。如果運行的時候發現有的可 以運行,有的不能,可以嘗試將 phantomJS 改成 Chrome。
實現模擬登錄的方式有哪些
1.直接使用已知的Cookie訪問
先用瀏覽器登錄,獲取瀏覽器里的cookie字符串,然后封裝至請求頭。
2.模擬登錄后用session保持登錄狀態
使用session模擬登陸后,就會自動存儲一個cookie次從而保持住登錄狀態。
3.使用Selenium+PhantomJS訪問
Selenium庫提供了find_element(s)_by_xxx的方法來找到網頁中的輸入框、按鈕等元素。其中xxx可以是id、name、tag_name(標簽名)、class_name(class),也可以是xpath(xpath表達式)等等。當然還是要具體分析網頁源代碼。
線程+進程+多線程
關系:一個程序至少有一個進程,一個進程至少有一個線程。
線程的順序:
新建:線程創建(t=threading.Thread(target=方法名)或者線程類)
就緒:當啟動線程后,線程就進入就緒狀態,就緒狀態的線程會被放到一個CPU調度隊列里面,cpu會負責讓其中的線程運行,變為運行狀態。
運行狀態:CPU調度一個就緒狀態的線程,該線程就變為運行狀態。
阻塞狀態:當運行狀態的線程被阻塞變為阻塞狀態,阻塞狀態的線程就會重新變為就緒狀態才能繼續運行。
死亡狀態:線程執行完畢。
多線程和多進程優缺點
多線程的優點:
程序邏輯和控制方式復雜;
所有線程可以直接共享內存和變量;
線程方式消耗的總資源比進程方式好。
多線程缺點:
每個線程與主程序共用地址空間,受限于2GB地址空間;
線程之間的同步和加鎖控制比較麻煩;
一個線程的崩潰可能影響到整個程序的穩定性;
多進程優點:
每個進程互相獨立,不影響主程序的穩定性,子進程崩潰沒關系;
通過增加CPU,就可以容易擴充性能;
每個子進程都有2GB地址空間和相關資源,總體能夠達到的性能上限非常大 。
多進程缺點:
邏輯控制復雜,需要和主程序交互;
需要跨進程邊界,如果有大數據量傳送,就不太好,適合小數據量傳送、密集運算 多進程調度開銷比較大。
在實際開發中,選擇多線程和多進程應該從具體實際開發來進行選擇。最好是多進程和多線程結合。
互斥鎖和死鎖和GLF鎖
1.互斥鎖
定義:當多個線程幾乎同時修改某一個共享數據的時候,需要進行同步控制。線程同步能夠保證多個線程安全訪問“競爭資源”,最簡單的同步機制就是引用互斥鎖。
由于線程共享進程的內存空間和數據,因此在某個線程要共享數據時,先將其鎖定,此時資源的狀態為“鎖定”,其他線程不能更改;直到該線程釋放資源,將資源的狀態變成“非鎖定”,其他的線程才能再次鎖定該資源。互斥鎖保證了每次只有一個線程進入寫入操作,從而保證了多線程情況下數據的正確性。互斥鎖體現的就是一個同步的機制,即該線程釋放資源就是一個條件,條件完成,才能執行下一步操作。是微觀的操作。
鎖的好處:
(1)確定了某段代碼只能由一個線程從頭到尾完整地執行。
(2)全局變量的安全
鎖的壞處:
(1)阻止了多線程的并發執行,包含鎖的某段代碼實際上只能以單線程模塊執行,效率降低
(2)由于可以存在多個鎖,不同的線程持有不同的鎖,并試圖獲取對方持有的鎖的時,可能會造成“死鎖”。
2.死鎖
(1)同一個線程先后兩次調用lock,在第二次調用時,由于鎖已經被自己占用,該線程會掛起等待自己釋放鎖,由于該線程已被掛起而沒有機會釋放鎖,因此 它將一直處于掛起等待狀態,變為死鎖;
(2)線程A獲得了鎖1,線程B獲得了鎖2,這時線程A調用lock試圖獲得鎖2,結果是需要掛起等待線程B釋放鎖2,而這時線程B也調用lock試圖獲得鎖1,結果是需要掛起等待線程A釋放鎖1,于是線程A和B都在等待對方釋放自己才釋放,從而造成兩個都永遠處于掛起狀態,造成死鎖。
3.有GLF鎖為什么還要有互斥鎖
(1)為什么設計GLF鎖?
Python 在設計之初就考慮到要在解釋器的主循環中,同時只有一個線程在執行,即在任意時刻,只有一個線程在解釋器中運行。對Python 虛擬機的訪問由全局解釋器鎖(GIL)來控制,正是GIL鎖能保證同一時刻只有一個線程在運行。
(2)宏觀微觀考慮GLF鎖?
GIL是宏觀的操作。比如在一個4核的環境下,只有一個核是運行著線程,而其他三個核是空的。GIL是線程鎖,針對線程,而不是進程。
MongoDB
MongoDB和傳統的關系型數據庫區別:
1.傳統數據庫特點是存儲結構化數據,數據以行為單位,每行的數據結構和類型相同。
2.MongoDB存儲的是文檔,每個文檔得結構可以不相同,能夠更便捷的獲取數據。
3.MongoDB的集合不需要提前創建,可隱式創建,而關系型數據庫的表需要提前定義。
4.MongoDB第三方支持豐富。(這是與其他的NoSQL相比,MongoDB也具有的優勢)。
5.MongoDB不支持事務操作。
6.MongoDB支持大容量的存儲,占用空間過大。
MongoDB和SQL的對比:
游標:
定義:由于MongoDB底層是JS編寫,因此可以使用一些JS代碼,通俗的說游標不是查詢結果,而是查詢的返回資源或者接口,就像Python中的生成器,通過這個生成器,可以一次一次的獲取每一個資源。
持久化:日志和快照對比
快照和日志兩者如何選擇?
推薦兩種共同使用:
1.如果Redis僅僅是用來做為緩存服務器的話,我們可以不使用任何的持久化。
2.一般情況下我們會將兩種持久化的方式都開啟。redis優先加載AOF文件來回復數據。RDB的好處是快速。
3.在主從節點中,RDB作為我們的備份數據,只在salve(從節點)上啟動,同步時間可以設置的長一點,只留(save 900 1)這條規則就可以了。
4.開啟AOF的情況下,主從同步是時候必然會帶來IO的性能影響,此時我們可以調大auto-aof-rewrite-min-size的值,比如5GB。來減少IO的頻率
5.不開啟AOF的情況下,可以節省IO的性能影響,這是主從間通過RDB持久化同步,但如果主從都掛掉,影響較大。
在dump rdb過程中,aof如果停止同步,會不會丟失?
答: 不會,所有的操作緩存在內存的隊列里,dump完成后,統一操作。
aof重寫是指什么?
答:由于日志保存的是所有操作命令,導致存的日志會過大,而且數據庫中有可能數據進行過刪除,因此日志中的一些命令就相當于無效,因此日志先會刪除,然后內存中的數據會逆化成命令,再重新寫入到日志文件中,以解決 aof日志過大的問。
如果rdb文件和aof文件都存在,優先用誰來恢復數據?
答: 在這種情況下,當Redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件完整。
恢復時rdb和aof哪個恢復的快?
答: rdb快,因為其是數據的內存映射,直接載入到內存,而aof是命令,需要逐條執行。
Scrapy和Scrapy-Redis
什么是Scrapy?
Scrapy 是一個快速、高層次的基于 Python 的 Web 爬蟲構架,它用于抓取Web 站點并從頁面中提取結構化的數據。Scrapy 使用了 Twisted異步網絡庫來處理網絡通訊。
Scrapy 常應用在包括數據挖掘,信息處理或存儲歷史數據等一系列的程序中。
Scrapy優缺點
優點:
Scrapy 是異步的(Scrapy 框架的異步機制是基于 twisted 異步網絡框架處理的,在 settings.py 文件里可以設置具體的并發量數值(默認是并發量 16))
采取可讀性更強的xpath代替正則
強大的統計和log系統
同時在不同的url上爬行
支持shell方式,方便獨立調試
寫middleware,方便寫一些統一的過濾器
通過管道的方式存入數據庫
缺點:
基于Python的爬蟲框架,擴展性比較差
基于twisted框架,運行中的exception是不會干掉reactor,并且異步框架出錯后是不會停掉其他任務的,數據出錯后難以察覺。
Scrapy的組件:
Scrapy和scrapy-redis的區別:
Scrapy是一個Python爬蟲框架,爬取效率極高,具有高度定制性,但是不支持分布式。而scrapy-redis一套基于redis數據庫、運行在Scrapy框架之上的組件,可以讓scrapy支持分布式策略,Slaver端共享Master端Redis數據庫里的item隊列、請求隊列和請求指紋集合
為什么選擇Redis數據庫,因為Redis支持主從同步,而且數據都是緩存在內存中的,所以基于Redis的分布式爬蟲,對請求和數據的高頻讀取效率非常高。
Redis的優點:
1.數據讀取快,因為數據都放在內存上
2.支持事務watch
3.數據持久化,支持快照和日志,方便恢復數據
4.擁有豐富的數據類型:list,string,set,qset,hash
5.支持主從復制,可以進行數據備份
6.豐富的特性:可以作為緩存,消息隊列,設置過期時間,到期自動刪除
分布式爬蟲主要解決什么問題?
IP、帶寬、CPU、io
Scrapy如何實現分布式抓取?
可以借助scrapy_redis類庫來實現。
在分布式爬取時,會有master機器和slave機器,其中,master為核心服務器,slave為具體的爬蟲服務器。
我們在master服務器上搭建一個Redis數據庫,并將要抓取的url存放到redis數據庫中,所有的slave爬蟲服務器在抓取的時候從redis數據庫中去鏈接,由于scrapy_redis自身的隊列機制,slave獲取的url不會相互沖突,然后抓取的結果最后都存儲到數據庫中。master的redis數據庫中還會將抓取過的url的指紋存儲起來,用來去重。相關代碼在dupefilter.py文件中的request_seen方法中可以找到。
定時任務:
1.可以設計一個定時的類,使用時間模塊(time,datetime),比如爬取時候獲取當前時間,再當前時間多久后再爬取
2.使用linux的crontab的計劃任務
crontab -l 列出所有的定時任務 看不到配置文件中寫的定時任務
crontab -e 新增計劃任務 跟上面的區別在于 沒有用戶名
crontab -r 清空計劃任務
分 時 日 月 周 命令
舉例使用:
* * * * * 命令 每分每時每天每月每周 執行這個命令
0-59 0-23 1-31 1-12 0-6 0是 周天 1-6 周一到周六
0 2 * * * mysqldump 每天的2點備份數據庫
0 2 * * 2 sync 每個周二的2點做數據同步
0 8 15 * * /home/jsgz.py 每個月15號的八點給大家算工資
0 */2 * * * /home/camera.py 每隔2個小時執行一次查看攝像頭
0 8,12,18 * * 1-5 kq.py 每周1-5 的 8點 12點 18點 執行打卡
0 8 * * * * spider.sh 每天 8點爬蟲
爬蟲框架、模塊
Python自帶:urllib,urllib2。
urllib和urllib2模塊都做與請求URL相關的操作,但他們提供不同的功能。
urllib2.:urllib2.urlopen可以接受一個Request對象或者url,(在接受Request對象時候,并以此可以來設置一個URL 的headers),urllib.urlopen只接收一個url。
urllib 有urlencode,urllib2沒有,因此總是urllib,urllib2常會一起使用的原因
第 三 方:Requests
Requests是一個HTTP庫, 它只是用來,進行請求,對于HTTP請求,他是一個強大的庫,下載,解析全部自己處理,靈活性更高,高并發與分布式部署也非常靈活,對于功能可以更好實現.
框 架:Scrapy
Scrapy是封裝起來的框架,他包含了下載器,解析器,日志及異常處理,基于多線程, twisted的方式處理,對于固定單個網站的爬取開發,有優勢,但是對于多網站爬取 100個網站,并發及分布式處理方面,不夠靈活,不便調整與括展。
MyISAM 與 InnoDB
MyISAM 與 InnoDB 兩個引擎有什么區別?
InnoDB 支持事務,MyISAM 不支持,這一點是非常之重要。事務是一種高級的處理方式,如果在一些列增刪改中只要哪個出錯還可以回滾還原,而 MyISAM就不可以了。
MyISAM 適合查詢以及插入為主的應用,InnoDB 適合頻繁修改以及涉及到安全性較高的應用。
InnoDB 支持外鍵,MyISAM 不支持。
MyISAM 是默認引擎,InnoDB 需要指定。
InnoDB 不支持 FULLTEXT 類型的索引。
InnoDB 中不保存表的行數,如 select count( * ) from table 時,InnoDB;需要掃描一遍整個表來計算有多少行,但是 MyISAM 只要簡單的讀出保存好的行數即 可。注意的是,當 count( * )語句包含 where 條件時 MyISAM 也需要掃描整個表。
對于自增長的字段,InnoDB 中必須包含只有該字段的索引,但是在 MyISAM表中可以和其他字段一起建立聯合索引。
清空整個表時,InnoDB 是一行一行的刪除,效率非常慢。MyISAM 則會重建表。
寫爬蟲是用多進程好?還是多線程好? 為什么?
IO密集型情況使用多線程;
計算密集型情況下使用多進程;
IO 密集型代碼(文件處理、網絡爬蟲等),多線程能夠有效提升效率(單線程下有 IO 操作會進行 IO 等待,造成不必要的時間浪費,而開啟多線程能在線程 A 等待時,自動切換到線程 B,可以不浪費 CPU 的資源,從而能提升程序執行效率)。在實際的數據采集過程中,既考慮網速和響應的問題,也需要考慮自身 機器的硬件情況,來設置多進程或多線程。
數據庫的優化
為什么要優化?
一個應用吞吐量瓶頸往往出現在數據庫的處理速度上,隨著應用程序的使用和業務的拓展,數據庫數據量逐漸增多,數據庫處理壓力逐漸增大,關系型數據庫數據存放在磁盤上的,讀寫速度較慢(與內存中的數據相比)。
優化方式:
設計表的時候嚴格根據數據庫的設計范式來設計數據庫;
select 后盡量不使用*;
盡量不使用嵌套查詢,使用連接查詢或者where查詢;
sql關鍵詞盡量使用大寫;
盡量使用邏輯外交不使用物理外鍵;
給查詢頻繁的字段添加索引,并且遵循最左原則(盡量將首選關鍵字段放在最前邊);
垂直分庫分表:把一些不經常讀的數據或者結果復雜的表拆分成多張表,較少磁盤I/O操作;
水平分庫分表:于數據量龐大的表,使用水平分庫分表;
使用緩存,把經常訪問到的數據而且不需要經常變化的數據放在緩存中,能節約磁盤IO;
優化硬件;
主從分離讀寫;采用主從復制把數據庫的讀操作和寫入操作分離開來。
使用過的解析數據包:Xpath、正則
怎么監控爬蟲的狀態
(1)使用 Python 的 STMP 包將爬蟲的狀態信心發送到指定的郵箱。
(2)Scrapyd、pyspider
(3)引入日志
panads讀取數據
import pandas as pd
# 加載detail
detail=pd.read_excel("./meal_order_detail.xlsx")
# 1、直接查看方式--先后索引
# 先列 后行的方式
# 獲取dishes_id counts amounts dishes_name 多列數據
res=detail[["dishes_id","counts","amounts","dishes_name"]]
# 獲取多列的前n行
res1=detail[["dishes_id", "counts", "amounts", "dishes_name"]][:20]
res2=detail[["dishes_id", "counts", "amounts", "dishes_name"]].head(20)
# res=detail[["dishes_id", "counts", "amounts", "dishes_name"]][[0,1,2,3,4]] # # 不可以的
# res=detail["dishes_id"][[0,1,2,3,4]] # 可以的
# print("獲取多列的結果:\n", res)
# 2、同時索引
# loc 只能使用名稱 ---注意:可以使用名稱切片---包含收尾
# iloc 只能使用下標
res3=detail.loc[:,"dishes_id":"counts"]
# 3、ix ---同時索引-----混合索引
# 既可以使用名稱,也可以使用下標
# res=detail.ix[0:4, "dishes_id":"counts"]
# res=detail.ix[0:4, 0:2] # 前面行使用名稱,列使用下標
#
# res=detail.ix[0:4, 0:"amounts"] # 錯誤的,不能混搭
# print("res:\n", res)
# 直接索引方式 # 速度最快
# loc iloc #速度適中 # 某些大的平臺上只封裝loc iloc方式 --推薦
# ix # 速度最慢 --在最新的版本中提示,將要被刪除掉
Nginx的正向代理和反向代理
Web 開發中,部署方式大致類似。簡單來說,使用 Nginx 主要是為了實現分流、轉發、負載均衡, 以及分擔服務器的壓力。Nginx 部署簡單,內存消耗少,成本低。Nginx 既可以做正向代理,也可以做反向代理。
正向代理:請求經過代理服務器從局域網發出,然后到達互聯網上的服務器。特點:服務端并不知道真正的客戶端是誰。
反向代理:請求從互聯網發出,先進入代理服務器,再轉發給局域網內的服務器。特點:客戶端并不知道真正的服務端是誰。
區別:正向代理的對象是客戶端。反向代理的對象是服務端。
緩存穿透、緩存擊穿、緩存雪崩
Redis技術就是NoSQL技術中的一種,但是引入Redis又有可能出現緩存穿透,緩存擊穿,緩存雪崩等問題。
1.緩存穿透:
(1)產生原因:key對應的數據在數據源并不存在,每次針對此key的請求從緩存獲取不到,請求都會到數據源,從而可能壓垮數據源。比如用一個不存在的用戶id獲取用戶信息,不論緩存還是數據庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮數據庫。
(2)解決方案:
①最常見的則是采用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。
②另外也有一個更為簡單粗暴的方法(我們采用的就是這種),如果一個查詢返回的數據為空(不管是數據不存在,還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。
2.緩存擊穿:
(1)產生原因:key對應的數據存在,但在redis中過期,此時若有大量并發請求過來,這些請求發現緩存過期一般都會從后端DB加載數據并回設到緩存,這個時候大并發的請求可能會瞬間把后端DB壓垮。
(2)解決方案:業界比較常用的做法,是使用mutex。簡單地來說,就是在緩存失效的時候(判斷拿出來的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一個mutex key,當操作返回成功時,再進行load db的操作并回設緩存;否則,就重試整個get緩存的方法。
3.緩存雪崩:
(1)產生原因:當緩存服務器重啟或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給后端系統(比如DB)帶來很大壓力。
(2)解決方案:
①緩存失效時的雪崩效應對底層系統的沖擊非??膳拢〈蠖鄶迪到y設計者考慮用加鎖或者隊列的方式保證來保證不會有大量的線程對數據庫一次性進行讀寫,從而避免失效時大量的并發請求落到底層存儲系統上。
②簡單方案就時講緩存失效時間分散開,比如我們可以在原有的失效時間基礎上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發集體失效的事件。
Python垃圾回收機制
引用計數是一種垃圾收集機制,而且也是一種最直觀,最簡單的垃圾收集技術。當 Python 的某個對象的引用計數降為 0 時,說明沒有任何引用指向該對象,該對象就成為要被回收的垃圾了。比如某個新建對象,它被分配給某個引用,對象的引用計數變為 1。如果引用被刪除,對象的引用計數為 0,那么該對象就可以被垃圾回收。不過如果出現循環引用的話,引用計數機制就不再起有效的作用了。
一般是類中的 __del方法進行的。
版權聲明:本文為CSDN博主「不愿透露姓名の網友」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_40558166/article/details/103044923
金三銀四招聘季,你還有哪些面試干貨文章呢?分享或者查看干貨文章可戳:
鈕點擊追蹤可能是網站運營中最常見的需求之一。現在,通過GA4 和 Google 跟蹤代碼管理器(GTM)的配合,我們可以輕易實現追蹤,甚至可以導入到google ads,輔助廣告優化。
具體實現方法有很多,本文主要介紹使用GTM的方法。
首先,我們需要創建一個觸發器,或更具體地說,創建一個通用點擊觸發器。這將允許 GTM 監聽與點擊相關的事件。
在 Google 跟蹤代碼管理器中,我們可以選擇 2 個點擊觸發選項:
? All Elements
? Just links
Just links是一種常見的方式,因為許多按鈕本質上是用戶點擊的裝飾鏈接。但是,如果您的按鈕恰好不是鏈接,您將無法獲得更多信息來跟蹤。
這就是為什么我們喜歡使用All Elements作為觸發器類型。此觸發器類型能夠偵聽任何內容(例如圖像、文件、按鈕、空白區域等)和鏈接上發生的點擊。它只是更通用、更通用。
創建一個新觸發器并選擇All Elements。
現在,GTM 可以識別何時發生點擊,無論是鏈接點擊還是任何元素點擊。
然而,我們可能需要更多的信息,而不僅僅是知道存在點擊交互。
要獲取有關點擊的信息,請轉到 Google 跟蹤代碼管理器并啟用與點擊相關的所有內置變量。這些變量將為我們提供所需的大部分點擊詳細信息,例如Click Text,它會顯示按鈕上的文本。
在 GTM 工作區中,選擇Variables,然后選擇Configure。
啟用所有單擊變量。
該信息將用于創建觸發我們的標簽的條件。
返回我們的產品頁面,讓我們單擊Add to Cart按鈕。(在這里,添加購物車僅僅是示例,你可以把這個方法應用在任何按鈕)
前往 Google 跟蹤代碼管理器的調試界面。識別Summary下的Click事件并選擇它。查看之前啟用的變量向我們展示了什么信息。
這里我們需要找到足夠獨特的數據作為觸發條件。
在“調試”界面中,選擇左側面板中的Click事件,然后單擊Variables選項卡。
重點關注我們已啟用的變量(Click Classes, Click ID, Click Target, Click Text, and Click URL),盡力識別按鈕特有的數據。
通常,許多按鈕都是構建為鏈接的,這意味著您的 Click URL 變量值很有可能顯示鏈接。您可以將其用于您的觸發條件。
但是,很多時候并非所有維度的數據都齊全。在我們的示例中,Click URL沒有值,這時我們可以使用另外兩條信息:
? Click Classes,值為:single_add_to_cart_button button alt
? Click Text,值為: Add to cart
需要注意的是,Click Classes和Click Text很有可能不是唯一值,該方法只適用于追蹤網站所有同類按鈕。
如果我們僅僅只需要追蹤與 Ninja 產品的添加到購物車按鈕,怎樣才能做到這一點呢?
首先,我們需要確保該按鈕是唯一的,并且在整個網站中不會重復。
為此,我們將使用 Chrome 開發人員工具。如果您不熟悉,只需按照以下步驟操作即可。
右鍵單擊您的按鈕并選擇檢查。
這將使您能夠訪問瀏覽器的開發人員工具來查看按鈕的 HTML 和 CSS 源代碼。
單擊鍵盤上的CTRL + F來過濾 HTML 文檔。
復制并粘貼該類并將其粘貼到過濾器中。我們將復制粘貼single_add_to_cart_button 按鈕 alt。
過濾器將顯示您的網站上存在多少個此類。
如果過濾器結果是1 of 1 ,這意味著該按鈕的類僅有唯一一項。使用與此按鈕相關的 GTM 點擊類只會跟蹤此按鈕,而不會跟蹤另一個按鈕。
如果結果超過 1 個,而您只想追蹤特定按鍵,不是同類的所有按鍵,則需要進一步過濾。
解決方案是在觸發器中添加頁面 URL ,以僅跟蹤位于 Flying Ninja 海報所在位置的“添加到購物車”按鈕。
讓我們回到All Elements觸發器。
默認情況下,我們的觸發器會幫助我們檢測所有用戶點擊。我們需要從All Clicks切換為Some Clicks。
接下來是觸發條件的設置,在我們的例子中是:Click Classes → contains → single_add_to_cart_button
重命名您的觸發器并保存。
首先,我們創建一個新的 GA4 事件代碼。 Tag Type選擇Google Analytics: GA4 Event,再根據GA4的衡量ID對應選擇Configuration Tag。如果沒有預設的Tag,則選擇None - Manually Set ID,再手動填入衡量ID即可。
然后我們需要命名我們的事件。建議button_click。遵從Google 的命名規則的最佳實踐是小寫字母加下劃線。
此外,最好不要發明名稱,而應該首先查看 Google 跟蹤的內容。增強測量中會跟蹤點擊次數,但沒有任何特定于按鈕點擊的內容。他們將事件命名為Click,我們也可以使用它。
此時,我們可以像這樣將事件發送到 GA4。
但是,我們希望向 GA4 發送有關此次點擊的更多詳細信息,因此我們將使用事件參數。
按鈕的文本和頁面位置對我們很有價值,因此我們將添加 2 個自定義參數。
我們的設置如下所示。
? 注意:我們討論的命名事件的方法與命名事件參數的方法相同。建議使用推薦事件或增強測量列表中任何適合您需求的事件。如果您選擇為事件參數使用自定義名稱,并且想要在 GA4 報告(自定義維度)中使用,則參數的數量將被限制為 50 個。
Google 的推薦事件和增強型測量沒有與按鈕文本相關的參數。我們能找到的最接近的是link_text。link_text參數用于文件下載 。
你也可以自定義Parameter Name。例如,button_text,甚至click_text。
由于目標是顯示按鈕文本的值,因此我們可以從之前啟用的Click Text變量中獲取值。
選擇Click Text。
如果我們還想知道按鈕所在的頁面。只需重復上述過程并在Value下選擇Page頁面 URL即可。
添加我們之前創建的所有觸發器。
保存您的標簽。
啟用Preview模式并單擊Add to cart按鈕。
您可以看到我們的標簽已觸發。
在 GA4 的 DebugView 中,您將看到即將發生的事件。
在參數旁邊,您可以看到我們的link_text和page_location事件參數及其值。
至此,事件創建已經完成。最多不超過48小時,我們就可以在GA4的事件中找到它,也可以用它創建轉化和受眾。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。