1. 寫一個郵箱地址的正則表達(dá)式?
[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
2. 談一談你對 Selenium 和 PhantomJS 了解
Selenium 是一個Web 的自動化測試工具,可以根據(jù)我們的指令,讓瀏覽器自動加載頁面,獲取需要的數(shù)據(jù),甚至頁面截屏,或者判斷網(wǎng)站上某些動作是否發(fā)生。Selenium 自己不帶瀏覽器,不支持瀏覽器的功能,它需要與第三方瀏覽器結(jié)合在一起才能使用。但是我們有時(shí)候需要讓它內(nèi)嵌在代碼中運(yùn)行,所以我們可以用一個叫 PhantomJS 的工具代替真實(shí)的瀏覽器。Selenium庫里有個叫 WebDriver 的API。WebDriver 有點(diǎn)兒像可以加載網(wǎng)站的瀏覽器,但是它也可以像BeautifulSoup 或者其他Selector 對象一樣用來查找頁面元素,與頁面上的元素進(jìn)行交互 (發(fā)送文本、點(diǎn)擊等),以及執(zhí)行其他動作來運(yùn)行網(wǎng)絡(luò)爬蟲。
PhantomJS是一個基于 Webkit 的“無界面”(headless)瀏覽器,它會把網(wǎng)站加載到內(nèi)存并執(zhí)行頁面上的 JavaScript,因?yàn)椴粫故緢D形界面,所以運(yùn)行起來比完整的瀏覽器要高效。相比傳統(tǒng)的Chrome或 Firefox 瀏覽器等,資源消耗會更少。
如果我們把 Selenium 和 PhantomJS 結(jié)合在一起,就可以運(yùn)行一個非常強(qiáng)大的網(wǎng)絡(luò)爬蟲了,這個爬蟲可以處理 JavaScrip、Cookie、headers,以及任何我們真實(shí)用戶需要做的事情。主程序退出后,selenium 不保證 phantomJS 也成功退出,最好手動關(guān)閉 phantomJS 進(jìn)程。(有可能會導(dǎo)致多個 phantomJS 進(jìn)程運(yùn)行,占用內(nèi)存)。WebDriverWait 雖然可能會減少延時(shí),但是目前存在 bug(各種報(bào)錯),這種情況可以采用 sleep。phantomJS爬數(shù)據(jù)比較慢,可以選擇多線程。如果運(yùn)行的時(shí)候發(fā)現(xiàn)有的可以運(yùn)行,有的不能,可以嘗試將 phantomJS 改成 Chrome。
3. 為什么 requests 請求需要帶上 header?
原因是:模擬瀏覽器,欺騙服務(wù)器,獲取和瀏覽器一致的內(nèi)容
header 的形式:字典
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
用法: requests.get(url,headers=headers)
4. 你遇到的反爬蟲策略有哪些?及應(yīng)對策略有什么?
- 通過headers反爬蟲
- 基于用戶行為的發(fā)爬蟲:例如同一IP短時(shí)間內(nèi)多次訪問同一頁面,或者同一賬戶短時(shí)間內(nèi)多次進(jìn)行相同操作
- 動態(tài)網(wǎng)頁反爬蟲,例如:我們需要爬取的數(shù)據(jù)是通過ajax請求得到,或者通過JavaScript生成的
- 對部分?jǐn)?shù)據(jù)進(jìn)行加密處理的,例如:我們要抓的數(shù)據(jù)部分能夠抓到,另外的部分加密處理了,是亂碼
應(yīng)對策略:
- 對部分?jǐn)?shù)據(jù)進(jìn)行加密處理的,例如:我們要抓的數(shù)據(jù)部分能夠抓到,另外的部分加密處理了,是亂碼
- 1.對于基本網(wǎng)頁的抓取可以自定義headers,添加headers的數(shù)據(jù),代理來解決
- 有些網(wǎng)站的數(shù)據(jù)抓取必須進(jìn)行模擬登陸才能抓取到完整的數(shù)據(jù),所以要進(jìn)行模擬登陸。
- 對于限制抓取頻率的,可以設(shè)置抓取的頻率降低一些,
- 對于限制ip抓取的可以使用多個代理ip進(jìn)行抓取,輪詢使用代理
- 針對動態(tài)網(wǎng)頁的可以使用
selenium+phantomjs進(jìn)行抓取,但是比較慢,所以也可以使用查找接口的方式進(jìn)行抓取。
- 對部分?jǐn)?shù)據(jù)進(jìn)行加密的,可以使用selenium進(jìn)行截圖,飯后使用python自帶的
pytesseract庫進(jìn)行識別,但是比較慢最直接的方法是找到加密的方法進(jìn)行逆向推理。
5. 分布式爬蟲原理?
scrapy-redis實(shí)現(xiàn)分布式,其實(shí)從原理上來說很簡單,這里為描述方便,我們把自己的核心服務(wù)器稱為 master,而把用于跑爬蟲程序的機(jī)器稱為 slave。
我們知道,采用 scrapy 框架抓取網(wǎng)頁,我們需要首先給定它一些 start_urls,爬蟲首先訪問 start_urls里面的 url,再根據(jù)我們的具體邏輯,對里面的元素、或者是其他的二級、三級頁面進(jìn)行抓取。而要實(shí)現(xiàn)分布式,我們只需要在這個 starts_urls 里面做文章就行了。
我們在 master 上搭建一個 redis 數(shù)據(jù)庫(注意這個數(shù)據(jù)庫只用作 url 的存儲,不關(guān)心爬取的具體數(shù)據(jù),不要和后面的 mongodb 或者 mysql 混淆),并對每一個需要爬取的網(wǎng)站類型,都開辟一個單獨(dú)的列表字段。通過設(shè)置 slave 上 scrapy-redis 獲取 url 的地址為 master 地址。這樣的結(jié)果就是,盡管有多個 slave,然而大家獲取 url 的地方只有一個,那就是服務(wù)器 master 上的 redis 數(shù)據(jù)庫。并且,由于 scrapy-redis 自身的隊(duì)列機(jī)制,slave 獲取的鏈接不會相互沖突。這樣各個 slave 在完成抓取任務(wù)之后,再把獲取的結(jié)果匯總到服務(wù)器上(這時(shí)的數(shù)據(jù)存儲不再在是 redis,而是 mongodb 或者mysql等存放具體內(nèi)容的數(shù)據(jù)庫了)這種方法的還有好處就是程序移植性強(qiáng),只要處理好路徑問題,把 slave 上的程序移植到另一臺機(jī)器上運(yùn)行,基本上就是復(fù)制粘貼的事情。
6. pythoon2.x 中urllib和urllib2的區(qū)別?
異同:都是做url請求的操作的,但是區(qū)別很明顯。
- urllib2可以接受一個Request類的實(shí)例來設(shè)置URL請求的headers,urllib僅可以接受URL。這意味著,你不可以通過urllib模塊偽裝你的User Agent字符串等(偽裝瀏覽器)。
- urllib提供urlencode方法用來GET查詢字符串的產(chǎn)生,而urllib2沒有。這是為何urllib常和urllib2一起使用的原因。
- 模塊比較優(yōu)勢的地方是urlliburllib2.urlopen可以接受Request對象作為參數(shù),從而可以控制HTTP Request的header部。
- 但是urllib.urlretrieve函數(shù)以及urllib.quote等一系列quote和unquote功能沒有被加入urllib2中,因此有時(shí)也需要urllib的輔助。
7.robots協(xié)議是什么?
Robots協(xié)議(也稱為爬蟲協(xié)議、爬蟲規(guī)則、機(jī)器人協(xié)議等)也就是robots.txt,網(wǎng)站通過robots協(xié)議告訴搜索引擎哪些頁面可以抓取,哪些頁面不能抓取。
Robots協(xié)議是網(wǎng)站國際互聯(lián)網(wǎng)界通行的道德規(guī)范,其目的是保護(hù)網(wǎng)站數(shù)據(jù)和敏感信息、確保用戶個人信息和隱私不被侵犯。因其不是命令,故需要搜索引擎自覺遵守。
8.什么是爬蟲?
爬蟲是請求網(wǎng)站并提取數(shù)據(jù)的自動化程序
9.爬蟲的基本流程?
- 1、通過http庫向目標(biāo)站點(diǎn)發(fā)起請求,即發(fā)送一個Request,請求可以包含額外的headers等信息,等待服務(wù)器響應(yīng)
- 2、如果服務(wù)器能正常響應(yīng),會得到一個Response,Response的內(nèi)容比啊是索要獲取的頁面內(nèi)容
- 3、解析內(nèi)容:正則表達(dá)式、頁面解析庫、json
- 4、保存數(shù)據(jù):文本或者存入數(shù)據(jù)庫
10.什么是Request和Response?
本地 向 服務(wù)器 發(fā)送Request,服務(wù)器根據(jù)請求返回一個Response,頁面就顯示在頁面上了
- 1、瀏覽器就發(fā)送消息給該網(wǎng)址所在的服務(wù)器,這個過程叫做
Http Request- 2、服務(wù)器收到瀏覽器發(fā)送的消息后,能夠根據(jù)瀏覽器發(fā)送消息的內(nèi)容,做相應(yīng)處
理,然后把消息回傳給瀏覽器,這個過程叫做HTTP Response- 3、瀏覽器收到服務(wù)器的Response消息后,會對信息進(jìn)行相應(yīng)處理,然后顯示
11.Request中包含什么呢?
- 1、請求方式:主要有
GET和POST兩種方式,POST請求的參數(shù)不會包含在url里面- 2、請求URL
URL:統(tǒng)一資源定位符,如一個網(wǎng)頁文檔、一張圖片、一個視頻等都可以用URL來唯一確定- 3、請求頭信息,包含了
User-Agent(瀏覽器請求頭)、Host、Cookies信息- 4、請求體,
GET請求時(shí),一般不會有,POST請求時(shí),請求體一般包含form-data
12.Response中包含什么信息?
- 1、響應(yīng)狀態(tài):狀態(tài)碼 正常響應(yīng)200 重定向
- 2、響應(yīng)頭:如內(nèi)容類型、內(nèi)容長度、服務(wù)器信息、設(shè)置cookie等
- 3、響應(yīng)體信息:響應(yīng)源代碼、圖片二進(jìn)制數(shù)據(jù)等等
13.常見的http狀態(tài)碼
200狀態(tài)碼服務(wù)器請求正常301狀態(tài)碼:被請求的資源已永久移動到新位置。服務(wù)器返回此響應(yīng)(對 GET 或 HEAD 請求的響應(yīng))時(shí),會自動將請求者轉(zhuǎn)到新位置。302狀態(tài)碼:請求的資源臨時(shí)從不同的URI響應(yīng)請求,但請求者應(yīng)繼續(xù)使用原有位置來進(jìn)行以后的請求401狀態(tài)碼:請求要求身份驗(yàn)證。 對于需要登錄的網(wǎng)頁,服務(wù)器可能返回此響應(yīng)。403狀態(tài)碼:服務(wù)器已經(jīng)理解請求,但是拒絕執(zhí)行它。與401響應(yīng)不同的是,身份驗(yàn)證并不能提供任何幫助,而且這個請求也不應(yīng)該被重復(fù)提交。404狀態(tài)碼:請求失敗,請求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)。500狀態(tài)碼:服務(wù)器遇到了一個未曾預(yù)料的狀況,導(dǎo)致了它無法完成對請求的處理。一般來說,這個問題都會在服務(wù)器的程序碼出錯時(shí)出現(xiàn)。503狀態(tài)碼:由于臨時(shí)的服務(wù)器維護(hù)或者過載,服務(wù)器當(dāng)前無法處理請求。
14.HTTP 的請求和響應(yīng)都包含哪些內(nèi)容
HTTP請求頭
- Accept:瀏覽器能夠處理的內(nèi)容類型
- Accept-Charset:瀏覽器能夠顯示的字符集
- Accept-Encoding:瀏覽器能夠處理的壓縮編碼
- Accept-Language:瀏覽器當(dāng)前設(shè)置的語言
- Connection:瀏覽器與服務(wù)器之間連接的類型
- Cookie:當(dāng)前頁面設(shè)置的任何Cookie
- Host:發(fā)出請求的頁面所在的域
- Referer:發(fā)出請求的頁面的URL
- User-Agent:瀏覽器的用戶代理字符串
HTTP響應(yīng)頭部信息:
- Date:表示消息發(fā)送的時(shí)間,時(shí)間的描述格式由rfc822定義
- server:服務(wù)器名字。
- Connection:瀏覽器與服務(wù)器之間連接的類型
- content-type:表示后面的文檔屬于什么MIME類型
- Cache-Control:控制HTTP緩存
15. mysql的索引在什么情況下失效
- 1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是為什么盡量少用or的原因)
要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引- 2.對于多列索引,不是使用的第一部分,則不會使用索引
- 3.
like查詢以%開頭- 4.如果列類型是字符串,那一定要在條件中將數(shù)據(jù)使用引號引用起來,否則不使用索引
- 5.如果
mysql估計(jì)使用全表掃描要比使用索引快,則不使用索引
15.MySQL 有什么引擎,各引擎之間有什么區(qū)別?
主要 MyISAM 與 InnoDB 兩個引擎,其主要區(qū)別如下:
- 1、InnoDB 支持事務(wù),MyISAM 不支持,這一點(diǎn)是非常之重要。事務(wù)是一種高級的處理方式,如在一些列增刪改中只要哪個出錯還可以回滾還原,而 MyISAM就不可以了;
- 2、MyISAM 適合查詢以及插入為主的應(yīng)用,InnoDB 適合頻繁修改以及涉及到安全性較高的應(yīng)用;
- 3、InnoDB 支持外鍵,MyISAM 不支持;
- 4、MyISAM 是默認(rèn)引擎,InnoDB 需要指定;
- 5、InnoDB 不支持 FULLTEXT 類型的索引;
- 6、InnoDB 中不保存表的行數(shù),如 select count() from table 時(shí),InnoDB;需要掃描一遍整個表來計(jì)算有多少行,但是 MyISAM 只要簡單的讀出保存好的行數(shù)即可。注意的是,當(dāng) count()語句包含 where 條件時(shí) MyISAM 也需要掃描整個表;
- 7、對于自增長的字段,InnoDB 中必須包含只有該字段的索引,但是在 MyISAM表中可以和其他字段一起建立聯(lián)合索引;
- 8、清空整個表時(shí),InnoDB 是一行一行的刪除,效率非常慢。MyISAM 則會重建表;
- 9、InnoDB 支持行鎖(某些情況下還是鎖整表,如 update table set a=1 where user like '%lee%'
16.Scrapy優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
- scrapy 是異步的
- 采取可讀性更強(qiáng)的xpath代替正則
- 強(qiáng)大的統(tǒng)計(jì)和log系統(tǒng)
- 同時(shí)在不同的url上爬行
- 支持shell方式,方便獨(dú)立調(diào)試
- 寫middleware,方便寫一些統(tǒng)一的過濾器
- 通過管道的方式存入數(shù)據(jù)庫
缺點(diǎn):基于python的爬蟲框架,擴(kuò)展性比較差
- 基于
twisted框架,運(yùn)行中的exception是不會干掉reactor,并且異步框架出錯后是不會停掉其他任務(wù)的,數(shù)據(jù)出錯后難以察覺。
17.HTTPS 是如何實(shí)現(xiàn)安全傳輸數(shù)據(jù)的
- 客戶端(通常是瀏覽器)先向服務(wù)器發(fā)出加密通信的請求
- 服務(wù)器收到請求,然后響應(yīng)
- 客戶端收到證書之后會首先會進(jìn)行驗(yàn)證
- 服務(wù)器收到使用公鑰加密的內(nèi)容,在服務(wù)器端使用私鑰解密之后獲得隨機(jī)數(shù)pre-master secret,然后根據(jù)radom1、radom2、pre-master secret通過一定的算法得出session Key和MAC算法秘鑰,作為后面交互過程中使用對稱秘鑰。同時(shí)客戶端也會使用radom1、radom2、pre-master secret,和同樣的算法生成session Key和MAC算法的秘鑰。
- 然后再后續(xù)的交互中就使用session Key和MAC算法的秘鑰對傳輸?shù)膬?nèi)容進(jìn)行加密和解密。
18.描述下scrapy 框架運(yùn)行的機(jī)制?
從start_urls里獲取第一批url并發(fā)送請求,請求由引擎交給調(diào)度器入請求隊(duì)列,獲取完畢后,調(diào)度器將請求隊(duì)列里的請求交給下載器去獲取請求對應(yīng)的響應(yīng)資源,并將響應(yīng)交給自己編寫的解析方法做提取處理:
- 如果提取出需要的數(shù)據(jù),則交給管道文件處理;
- 如果提取出url,則繼續(xù)執(zhí)行之前的步驟(發(fā)送url請求,并由引擎將請求交給調(diào)度器入隊(duì)列...),直到請求隊(duì)列里沒有請求,程序結(jié)束。