1. 程式人生 > >筆試題1

筆試題1

一、填空題

  1. list1 = [x for x in range(5, 2, -1)],則列印list1的結果是_____[5, 4, 3]______。
  2. 資料庫大致分為哪幾種類型,列舉你學過的資料庫名稱。 關係型資料庫和非關係型資料庫 Mysql redis mongodb sqlite3
  3. 字典和列表的區別有哪些? i)字典通過鍵建立與值得關係,列表通過索引建立和值得關係。 ii)字典儲存得資料不是按照資料新增得先後順序儲存的,而列表是按照資料新增得先後順序儲存得。 iii)字典通過鍵取值,不支援切片查詢;列表通過索引取值,支援切片查詢。
  4. Scrapy建立專案、建立爬蟲、執行爬蟲的命令分別為 scrapy startproject spider Scrapy genspider zhihu
    zhihu.com
    Scrapy crawl zhihu
  5. 列舉常用的資料解析方式及解析用到的包 Xpath、css、bs4、lxml 6.寫一個匿名函式,用於計算兩個數的和 。 lambda x,y: x+y 二、判斷題 1.Python中宣告變數時,需要在變數前新增變數型別。 錯 2.print(a//b)輸出中,a//b是取整運算子。 對 3.列表是支援索引切片查詢的,但是字串也是支援切片查詢得。 對 4.元組是可變的資料型別,可以進行增刪改查的操作。 錯 5.形參是用來給實參賦值的,形參在呼叫函式的時候使用,實參在宣告函式的時候使用。 錯 6.python中的類是不支援繼承的。 錯 7.字典是不可變的,不能進行增刪改查的操作。 錯

二、簡答題 1.通過程式碼建立一個.xls的檔案到本地,並寫入多條資料,比如姓名,年齡,身高,體重等。 import xlwt book = xlwt.Workbook() sheet = book.add_sheet(‘stu’) sheet.write(0, 0, ‘姓名’) sheet.write(0, 1, ‘年齡’) sheet.write(0, 2, ‘身高’) sheet.write(0, 3, ‘體重’)

list1 = [(‘zhangsan’,‘20’,‘180’,‘80’), (‘lisi’,‘30’,‘170’,‘60’)] row = 1 for name, age, height, weight in list1: sheet.write(row, 0, name) sheet.write(row, 1, age) sheet.write(row, 2, height) sheet.write(row, 3, weight) row += 1

book.save(‘stu.xls’)

2.類中的關鍵字self和super的區別是什麼? self在類中表示當前類得物件。 Super在類中表示當前類。

3.requests模組如何實現cookie的自動化管理,通過程式碼將主要邏輯實現出來。 From http.cookiejar import LWPCookiejar Import requests

Session = requests.Session() Session.cookies = LWPCookieJar(filename=’test.txt’) Response = session.get()/session.post() #儲存cookie Session.cookies.save() #載入cookie Session.cookie.load()

4.GET請求和POST請求的區別有哪些? 1>GET請求將引數設定在url中,以?和&得形式拼接;POST請求將引數設定在請求體中; 2>GET請求沒有POST請求安全,重要資料容易暴露; 3>GET請求一般用於獲取伺服器資源;POST請求用於在伺服器上建立資源。

5.cookie和session的區別是什麼?詳細描述cookie和session中間的互動過程。 區別:cookie儲存在客戶端。Session儲存在伺服器端。 互動過程: 1>用於首次訪問網站的時候,伺服器會通過Set-Cookie欄位向客戶端返回一些cookie資訊; 2>客戶端在接收到伺服器響應之後,會解析響應頭中得Set-Cookie欄位,將資料快取在本地; 3>客戶端再次訪問伺服器得時候,會在請求頭中攜帶這些cookie資訊,用於表明客戶端和伺服器之間得連線狀態;

6.類的繼承有哪些優勢?面向物件的三大特徵是什麼? 優勢:繼承可以實現程式碼得重用,可以在父類已有功能得基礎上,擴充套件新得功能。 特徵:多型、繼承、封裝。

7.正則表示式中的.和.?的區別是什麼? .*: 貪婪匹配,在能夠匹配正確結果得前提下,儘可能多得匹配字元。 .*?: 非貪婪匹配,在能夠匹配正確結果得前提下,儘可能少得匹配字元。

8.scrapy是什麼?有哪些優勢? Scrapy是一個爬蟲框架。 優勢: 1>擴充套件性強,可以自定義管道和中介軟體; 2>速度快,是一個基於非同步多執行緒得框架; 3>自由控制爬蟲得爬取速度,執行緒數,併發數等控制爬蟲爬取過快得方法;

9.列舉網站中常見的反爬蟲措施。 User-Agent Cookie 代理IP 請求頭Host、Referer 多賬號

10.類中的__init__()函式的作用是什麼? init()是對一個類得物件進行初始化得操作。

11.scrapy各部分之間的資料流向是如何互動的,詳細描述一下。 1>引擎將起始url構造成Request交給排程器; 2>排程器對Request物件生成指紋資訊,根據是否去重來決定是否將Request放入佇列中; 3>引擎從排程器得佇列中不斷得獲取下一個Request請求; 4>引擎將Reques請求交給下載器Downloader進行下載,期間會經過下載器中介軟體process_request得處理; 5>下載器下載完成以後,經過process_response將Response物件返回給引擎; 6>引擎將Response物件交給爬蟲Spider進行解析,提取資料,期間經過爬蟲中介軟體; 7>爬蟲Spider將提取得結果傳遞給引擎,引擎將item交給管道,將Request物件交給排程器繼續排程;

12.DownoadMiddleware的作用是什麼?如何自定義DownloadMiddleware,描述需要實現的函式。 作用:下載器中介軟體,可以在發起請求之前對Request物件新增必要得資訊,比如請求頭,Cookie等。 自定義: 需要實現process_request()函式和process_response()函式。

13.ItemPipeline的作用是什麼?如何自定義ItemPipeline,描述需要實現的函式。 作用:對爬蟲解析出來得item物件進行資料得儲存。 自定義:process_item()函式。

14.ItemLoader獲取的資料如何進行資料的提取和過濾的?描述原始資料到最終的結果的資料簡要過濾過程。 1>在建立item_loader物件得時候,會執行item物件中input_processor和output_processor得初始化; 2>在執行add_xpath、add_css、add_value函式得時候,會將提取得結果交給input_processor進行結果得處理,結果處理完以後暫時儲存在item_loader中; 3>等資料提取完畢,呼叫load_item()方法,執行output_processor將最終結果複製給item物件;

15.scrapy設定User-Agent的方式有哪幾種?簡要描述出來。 1>在settings.py中通過USER_AGENT進行配置; 2>在下載器中介軟體中得process_request函式中,通過request.headers.setdefault(b’User-Agent’, ‘’)設定; 3>在自定義得爬蟲檔案.py中,定義在headers = {‘User-Agent’: ‘ ’}中;

16.描述scrapy的url去重原理。 1>需要將dont_filter設定為False開啟去重,預設是True,沒有開啟去重; 2>對於每一個url得請求,排程器都會根據請求方法、請求url、請求體加密得到一個指紋資訊,並且將指紋資訊和集合中得指紋資訊進行比對,如果集合中已經存在這個資料,就不在將這個Request放入佇列中。如果集合中沒有存在這個加密後得資料,就將這個Request物件放入佇列中,等待被排程。

17.scrapy能實現自定義圖片的下載地址和圖片名稱嗎?如果可以,可以通過哪些函式實現? 可以。 Get_media_request()、file_path()、item_complated()

18.scrapy專案的settings.py檔案中:DOWNLOAD_DELAY的作用是什麼?ROBOTSTXT_OBEY的作用是什麼? DOWNLOAD_DELAY: 設定請求間隔時間,可以降低爬取速度; ROBOTSTXT_OBEY:用來控制是否遵循robot協議得配置,如果遵守,則網站得一部分內容是無法爬取得。

19.Python的虛擬環境是如何進入虛擬環境和檢視當前虛擬環境?為什麼需要搭建虛擬環境? Workon 1>搭建虛擬環境主要是為了保證環境得統一性,對於不同得應用建立專屬得python環境,比如針對後臺開發得django可以建立一個虛擬環境,針對爬蟲開發得應用可以建立一個虛擬環境,避免環境之間產生衝突。 2>可以避免一個環境造成得安裝包過的多,導致環境載入緩慢。

20.常見的css選擇器有哪幾種(至少列出5種)? class選擇器 Id選擇器 後代選擇器 父子選擇器 屬性選擇器 交集選擇器 偽類選擇器

21.Mysql資料庫和MongoDB資料庫的區別是什麼? Mysql是關係型資料庫,需要建立多張表,通過需要建立表於表之間得關係。 MongoDB是非關係型資料庫,不需要多張表,而是在一張表中通過鍵值得關係來儲存資料。

22.正則表示式match()和search()函式的區別是什麼? Match()只匹配一個結果,並且只有正確結果在目標字串得開頭位置才能匹配到,如果不在開頭位置,無法匹配。 Search()至匹配一個結果,但是正確結果可以在目標字串得任意位置。

23.JSON模組中dumps()和loads()函式的作用分別是什麼? Dumps: 將一個字典轉化為json字串 Loads: 將一個json字串轉化為字典

24.關鍵字return和yield的在函式中的作用分別是什麼? return是直接中斷函式的執行,並返回一個結果,return之後的程式碼不會執行。 yield也是返回一個結果,但是yield之後的程式碼仍然可以執行

函式內有return,這個函式是一個普通的有返回值的函式。 函式內有yield,這個函式是一個生成器物件。

25.通過列表生成式,生成這樣一個結果列表[1, 9, 25, 49, 81]。 [x * x for x in range(1, 11) if x%2 != 0]

26.selenium中driver.switch_to.window()方法和driver.switch_to.frame()方法的區別是什麼? driver.switch_to.window(): 切換視窗,一般是指多個標籤選項卡之間的切換,每一個選項卡都是一個window視窗; driver.switch_to.frame(): 切換html內部框架,一般是在html巢狀的有<iframe>標籤時會使用。

27.三種時間等待的區別: 1>time.sleep(); 2>WebDriverWait(…).until(…); 3>driver.implicitly_wait(); 1>強制等待固定的時間; 2>針對某一個元素設定智慧等待時間; 3>針對整個頁面的載入,設定一個智慧等待時間;

28.列舉你所用過的python內建裝飾器,至少2個。列舉你所用過的python內建裝飾器,至少2個。 @property @staticmethod @classmethod

一、填空題(每空1分,共18分) 1.寫一句程式碼計算1到100的和______。 reduce(lambda x,y: x+y, [x for x in range(1, 101)])

2.有列表a = [1,2,3,4,5,6,7,8,9],給出獲取列表a中偶數值的列表b=[2,4,6,8]的一行程式碼______。給出不使用for迴圈能夠生成列表a的一行程式碼_______。 [x for x in a if x%2 == 0] [x for x in range(1, 10)]

3.給出同時遍歷字典a的key,vlaue的方法___________。 for k,v in a.items(): print(k, v)

4.如果模組test.py是被匯入的,_name__的值是________,如果模組test.py是被直接執行的,_name__的值是_________。 分別是:test _main_

5.寫一個用於匹配所有class=”red”的標籤所包裹的文字資料的正則表示式________。 <.*?class=”red”.*?>(.*?)</.*?>

6.連線MySql資料庫的命令為________。 mysql -uroot -p

7.啟動Redis服務的cmd命令為________。 redis-server.exe redis.window.conf

8.你使用過的Python中的裝飾器有哪些,至少列舉五個_______。裝飾器得作用_______。 裝飾器:@property、@staticmethod、@classmethod、@every、@config 作用:在不改變函式原有結構的同時,給一個函式新增額外的功能。

9.Phantomjs是什麼_______。selenium是什麼_______。 phantomjs是載入js程式碼的引擎 selenium是自動化測試框架,可以用於瀏覽器的自動化執行

10.Mysql埠號______。Redis埠號_______。https埠號_____。 3306、6379、443

11.佇列queue資料得進出順序是_______。棧stack結構資料進出順序是______。 先進先出、先進後出

二、簡答題(每題4分,共64分) 1.描述極驗驗證碼破解的主要流程(三個重要步驟)。 a>通過分析網站找出能夠獲取極驗引數的url; b>請求這個url獲取極驗引數,將獲得的極驗引數上傳到驗證碼識別介面; c>將識別成功後的返回值,和其它表單資料一塊上傳至網站主伺服器請求網站資料即可;

2.抓包工具Charles作用是什麼?如何配置Charles抓取APP發起的http/https網路請求? Charles是一個抓包代理工具,用於攔截客戶端發起的http/https請求,然後Charles再將請求轉發至對方伺服器,從而達到攔截請求和資料的目的。 配置: a>先配置charles,它預設能過攔截http請求,讓其能夠監聽https請求需要新增443埠; b>讓手機和電腦連線同一個網路; c>在proxy_settings中,勾選能夠攔截代理請求的選項; d>在手機中安裝證書,然後再手機端傳送請求即可;

3.分散式爬蟲作用?Scrapy框架自身(不含其它元件)是否支援分散式爬蟲?為什麼? 作用:提高爬蟲的爬取速度。 scrapy自身不支援分散式爬蟲,需要配合著scrapy_redis才能實現。 原因:因為scrapy框架對於請求的set去重,以及請求的佇列queue都是在記憶體中建立的,多臺電腦是無法共享同一臺電腦的記憶體的,如果每臺電腦中的scrapy都有自己的set和queue,就達不到分散式的要求。

4.描述scrapy框架如何對Request請求做去重的? a>將request的請求url、請求方法、請求引數進行hash加密; b>將生成的加密資訊存放在set集合中,如果set中存在了這個資訊,就無法再新增到set中,只能新增不同的加密資訊到set中; c>如果這個加密資訊成功的新增到了set中,說明這個請求之前沒有操作過,就將這個請求物件request放入佇列中,等待著排程器排程;

5.Scrapy部署分散式爬蟲的主要步驟是什麼? a>將scrapy_redis整合到爬蟲專案中; b>在settings.py中配置scrapy_redis提供的過濾器和排程器,並配置redis的遠端連線地址; c>修改爬蟲類的繼承關係,並設定起始url的redis_key; d>將資料庫配置成遠端連線資料庫; e>啟動專案,通過命令向redis資料庫中新增起始的Url;

6.布隆去重的作用是什麼?常見的爬蟲去重策略有哪些? 作用:提升url去重的資料量,在url數量非常大的情況下,也可以保證記憶體的佔用很少。 策略: a>將url加密儲存到資料庫中,每次獲取新的url後,都和資料庫中的url進行對比,如果已經存在就跳過這個url的請求; b>利用set()集合進行去重; c>布隆去重;

7.Scrapyd的作用是什麼?缺點是什麼? 作用:是可以將爬蟲程式部署到伺服器上,在伺服器上執行爬蟲專案,因為伺服器比較穩定,比直接將專案執行在本機電腦上要安全,另外就是可以實現爬蟲的遠端啟動、停止、除錯。 缺點:它是通過介面來實現對爬蟲的監控的,並且是通過命令的形式操作介面的,命令太多,操作不太方便。

8.至少寫出5個selenium中用於定位標籤的函式。 Find_element_by_id() Find_element_by_class_name() Find_element_by_css_seletor() Find_element_by_name() Find_element_by_xpath()

9.各列舉五個常見的響應狀態碼、請求頭,及其所表示的含義。 200 GET請求成功 201 POST請求成功 301 URL重定向 403 請求被拒絕 400 無效的請求 500 內部伺服器錯誤

10.說出你在爬取一個網站時,是如何制定爬取策略並最終編寫程式碼的? a>分析網站型別,是靜態網站還是動態網站; b>分析網頁資料是否通過介面返回的json字串; c>分析網站是否需要登入,是否需要攜帶cookie; d>分析請求中的引數是否進行了js加密;如果js破解太難,可以嘗試通過手機APP端抓取; e>分析網站是否會出現驗證碼;

11.對於使用的@font-face進行數字字型加密的網站,如何解決加密字型之間的對映關係? a>分析網頁原始碼返回的加密資料是什麼型別的資料; b>如果原始資料是編碼後的資料,可以將字型檔案下載下來,轉化為xml檔案,分析原始資料和xml中資料的對應關係; c>如果原始資料也是有數字構成的,則可以通過影象處理模組Pillow和影象識別庫tesseract-ocr找到原始數字和真實資料之間的關係,通過dr.text()方法即可獲取對應關係; d>如果原始資料和真實資料之間的關係是固定不變的,可以直接定義出對映字典即可;

12.Redis資料庫和MySQL資料庫的區別,從多個方向對比兩個資料庫。 a>Redis資料庫可以儲存多型別資料、set/list/hash/str/等型別,而mysql只能儲存單一資料,比如數字、字串,不能儲存集合; b>Redis資料庫是非關係型資料庫,而mysql屬於關係型資料庫; c>Redis資料庫是記憶體型資料庫,訪問速度快,適合做資料快取;而Mysql是通過本地磁碟儲存資料的資料庫,訪問速度相對較慢;

13.描述使用selenium模擬登陸流程。 a>通過selenium訪問登入頁面的url地址; b>通過find_element_xxx等方法定位到使用者名稱和密碼輸入框; c>通過send_keys()方法向輸入框中填充資料; d>定位到登入按鈕,執行click()點選方法即可;

14.如果讓你自己實現一個cookie池,你有什麼樣的思路來實現cookie得管理和維護? a>需要設計三個主要元件,生成器開關、檢測器開關、API介面開關; b>生成器主要是用來模擬登入的,將所有的賬號和密碼生成對應的cookie,並將其儲存到資料庫中; c>檢測器需要定時將資料庫中的cookie獲取出來,進行檢測是否過期,如果過期將cookie從資料庫中刪除; d>API介面開關,可以負責提供介面,獲取隨機的cookie,查詢cookie的總數量等功能;

15.什麼是增量式爬蟲?根據不同的情況如何設計增量式爬蟲的爬取過程? 增量式爬蟲:就是爬蟲在後續的重複執行過程中,將已經爬取過的資料遮蔽掉不再執行相應的請求,而爬取那些新增的內容,以及發生變化的內容,保證資料庫中的資料是定期更新的。 如何設計: a>對於只有新增內容,原有內容不發生變化的網站(比如小說文字字數),可以通過簡單的url+請求方式+請求引數進行加密的形式來判斷一個Url之前是否爬取過,如果爬取過則丟棄,如果沒有爬取過則重新請求; b>對於原有內容發生變化,沒有新增內容的網站,可以通過將一個資訊的多個重要資料加密儲存,比如文章的更新時間、字數的大小,等下一次重新爬取的時候,如果發現這些資料變化了,就重新爬取這個url,如果沒有發生變化,就丟棄這個請求; c>對於既有新增內容,原有內容也會發生改變的網站,則可以結合以上兩種方式共同進行驗證,只要符合兩者中的任何一種情況,都重新爬取這個url。

16.pyspider和scrapy的優缺點各有什麼? pyspider優點: a>多執行緒+非同步; b>除錯程式碼視覺化; c>任務執行的實時監測; d>支援定時任務; pyspider缺點: a>程式從編寫到執行是在網頁中完成的,不支援斷點除錯,雖然能夠單步除錯,但是單步除錯和整體的執行,結果還是有差異的; b>程式的重新執行和啟動比較麻煩; c>官方文件不夠詳細,可擴充套件性不強;

scrapy優點: a>擴充套件性強,元件之間都是相互獨立的模組,配置檔案可以靈活的調整爬取速度、請求頭等資訊; b>多執行緒+非同步; c>除錯方便,可以靈活的設定日誌輸出的級別,方便對url的執行結果進行檢查; d>支援分散式爬蟲,配置簡單; scrapy缺點: a>不支援定時任務; b>各元件之間關係複雜,內容較多,不容易掌握;

三、程式設計題(每題6分,共18分) 1.寫程式獲取一個字串中的數字字元,並按照陣列形式輸出,例如 輸入:dgfhfgh25433bhku2894fgdhdy675gfh 輸出:[25433,2894,675]

import re string = “dgfhfgh25433bhku2894fgdhdy675gfh” pattern = re.compile(r“(\d+)”, re.S) results = re.findall(pattern, string)

r_list = [] for result in results: result = int(result) r_list.append(result) print(r_list)

2.現有一段json字串string,如何將string中的results中的衣服資訊儲存到excel檔案中,寫出具體程式碼 string = “{‘code’:0,’error’:’ok’,’results’:[{‘title’:’2018新款衛衣’,’price’:128,’id’:2802713},{‘title’:’2018秋款外套’,’price’:135,’id’:2201733},{‘title’:’初冬毛呢外套’,’price’:299,’id’:232410},{‘title’:’秋季爆款線衣’,’price’:198,’id’:24213},{‘title’:’Ins超火毛呢外套’,’price’:99,’id’:473124}]}”

import xlwt, json string = ‘{“results”:[{“title”:“2018新款衛衣”,“price”:128,“id”:2802713},{“title”:“2018秋款外套”,“price”:135,“id”:2201733},{“title”:“初冬毛呢外套”,“price”:299,“id”:232410},{“title”:“秋季爆款線衣”,“price”:198,“id”:24213},{“title”:“Ins超火毛呢外套”,“price”:99,“id”:473124}]}’ wb = xlwt.Workbook(encoding=“utf8”) sheet = wb.add_sheet(“yifu”) sheet.write(0, 0, “標題”) sheet.write(0, 1, “價格”) sheet.write(0, 2, “id”) row = 1 datas = json.loads(string).get(“results”) for data in datas: title = data.get(“title”) price = data.get(“price”) id = data.get(“id”) sheet.write(row, 0, title) sheet.write(row, 1, price) sheet.write(row, 2, id) row += 1 wb.save(‘data.xls’)

3.用列表推導式實現下列功能 a)建立list1,存放1-100(包含100)中既是2又是3倍數的數字。 [x for x in range(1, 101) if x % 6 == 0]

b)現有列表list1=[“張三”, “李三”, “張四”, “張五”, “李四”, “王三”, “王四”, “王五”],請將列表1中所有以’張’開頭的名字放到list2中。 [x for x in list1 if x[0] == “張”]