日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > python >内容正文

python

python爬虫面试遇到的问题

發(fā)布時(shí)間:2023/12/10 python 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python爬虫面试遇到的问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1python基礎(chǔ)
      • 1.1 列表生成式和生成器的區(qū)別 ?
      • 1.2 如何不用任何循環(huán)快速篩掉列表中的奇數(shù)元素 ?
      • 1.3 map和reduce的用法
      • 1.4 裝飾器的作用
      • 1.5 Python中__new__與__init方法的區(qū)別
      • 1.6 python中的設(shè)計(jì)模式
      • 1.7 lambda函數(shù),以及它有什么好處
    • 2 反爬問(wèn)題
      • 2.1 如何處理封IP的反爬
      • 2.2 如何處理驗(yàn)證碼
      • 2.3 代理問(wèn)題
      • 2.4 驗(yàn)證碼處理
      • 2.5 模擬登陸問(wèn)題
    • 3 數(shù)據(jù)庫(kù)問(wèn)題
      • 3.1 說(shuō)幾個(gè)redis中的數(shù)據(jù)類型和命令
      • 3.2 MySQL中的inner join和left join的區(qū)別 ?
    • 4 爬蟲問(wèn)題
      • 4.1 常用的網(wǎng)絡(luò)數(shù)據(jù)爬取方法
      • 4.2 設(shè)計(jì)一個(gè)基于session登錄驗(yàn)證的爬蟲方案
    • 5 框架問(wèn)題
      • 5.1 scrapy的基本結(jié)構(gòu)(五個(gè)部分都是什么,請(qǐng)求發(fā)出去的整個(gè)流程)
      • 5.2 scrapy的去重原理 (指紋去重到底是什么原理)
      • 5.4 scrapy中間件有幾類,分別在哪里起的作用(面向切面編程)
      • 6 分布式
      • 6.1 分布式原理
      • 6.2 分布式如何判斷爬蟲已經(jīng)停止了
      • 6.3 分布式去重原理
      • 6.4 分布式爬蟲的實(shí)現(xiàn):
        • 例子1
        • 例子2
    • 7 模擬登錄
      • 7.1 selenium模擬登錄,遇到驗(yàn)證碼:
      • 7.2 tesseract-OCR的在驗(yàn)證碼識(shí)別中的重訓(xùn)練與使用
      • 7.3 搭建IP代理池

1python基礎(chǔ)

1.1 列表生成式和生成器的區(qū)別 ?

  • 列表生成式和生成器都可以來(lái)生成一個(gè)列表。
  • 列表生成式生成的列表,所有元素對(duì)象被立即創(chuàng)建在內(nèi)存中,當(dāng)元素過(guò)多時(shí),勢(shì)必會(huì)占用過(guò)多內(nèi)存,
  • 要用到生成器,它即時(shí)創(chuàng)建一個(gè)生成器對(duì)象,未創(chuàng)建任何元素。生成器來(lái)生成一個(gè)列表,它不會(huì)立即創(chuàng)建大量的對(duì)象在內(nèi)存中。
  • 生成器的缺點(diǎn),沒(méi)有列表的方法,如append、len、index等等
  • 通過(guò)next方法來(lái)訪問(wèn)其元素,可通過(guò)循環(huán)打印出所有的元素

1.2 如何不用任何循環(huán)快速篩掉列表中的奇數(shù)元素 ?

用內(nèi)置函數(shù)filter配合匿名函數(shù)過(guò)濾掉數(shù)組中不符合條件的元素

print (filter(lambda x:x%2 ==0, [1,2,3,4,5])) #[2,4]

1.3 map和reduce的用法

map
map()函數(shù)接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是Iterable。

例子1:
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list?)
# [1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce

reduce:把一個(gè)函數(shù)作用在一個(gè)序列[x1, x2, x3, …]上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

例子1:

from functools import reduce def add(x, y):return x + y print(reduce(add, [1, 3, 5, 7, 9])) #25

1.4 裝飾器的作用

裝飾器本質(zhì)上是一個(gè)Python函數(shù),它可以讓其他函數(shù)在不需要做任何代碼變動(dòng)的前提下增加額外功能,提高了代碼的復(fù)用性。比如,在函數(shù)調(diào)用前后自動(dòng)打印日志,但又不希望修改now()函數(shù)的定義,這種在代碼運(yùn)行期間動(dòng)態(tài)增加功能的方式,稱之為“裝飾器”(Decorator)。

1.5 Python中__new__與__init方法的區(qū)別

_new_:它是創(chuàng)建對(duì)象時(shí)調(diào)用,會(huì)返回當(dāng)前對(duì)象的一個(gè)實(shí)例,可以用_new_來(lái)實(shí)現(xiàn)單例

_init_:它是創(chuàng)建對(duì)象后調(diào)用,對(duì)當(dāng)前對(duì)象的一些實(shí)例初始化,無(wú)返回值。

1.6 python中的設(shè)計(jì)模式

1.7 lambda函數(shù),以及它有什么好處

lambda 表達(dá)式,通常是在需要一個(gè)函數(shù),但是又不想費(fèi)神去命名一個(gè)函數(shù)的場(chǎng)合下使用,也就是指匿名函數(shù)
lambda函數(shù):首要用途是指點(diǎn)短小的回調(diào)函數(shù)

lambda [arguments]:expression >>> a=lambdax,y:x+y >>> a(3,11)

2 反爬問(wèn)題

2.1 如何處理封IP的反爬

因?yàn)榫W(wǎng)絡(luò)上的免費(fèi)代理平臺(tái)可用的IP數(shù)量太少,所以自己寫一個(gè)模塊去抓取平臺(tái)的IP來(lái)維護(hù)是沒(méi)有什么意義的。我選擇的是付費(fèi)代理,通過(guò)使用平臺(tái)的api在本地動(dòng)態(tài)維護(hù)一個(gè)IP緩存池來(lái)供給分布式架構(gòu)的爬蟲節(jié)點(diǎn)使用。這個(gè)緩存池不需要做IP有效性驗(yàn)證,因?yàn)槲业呐老x若下載某個(gè)Request徹底失敗后會(huì)把這個(gè)Request重新放回Request隊(duì)列,而且選擇一個(gè)好的代理平臺(tái)可以大大提高代理IP質(zhì)量。我常用的是快代理。緩存池的IP被取走一個(gè),池中的數(shù)量就減少一個(gè),當(dāng)數(shù)量少于M時(shí),再?gòu)钠脚_(tái)獲取N個(gè)。

2.2 如何處理驗(yàn)證碼

答:簡(jiǎn)單的驗(yàn)證碼可以通過(guò)預(yù)處理(灰度、二值化、去除干燥點(diǎn))驗(yàn)證碼圖片再使用tesseract庫(kù)來(lái)識(shí)別;
復(fù)雜一點(diǎn)的則接入付費(fèi)平臺(tái)識(shí)別。當(dāng)然,如果這個(gè)目標(biāo)網(wǎng)站的app端沒(méi)有驗(yàn)證碼的話,會(huì)優(yōu)先通過(guò)app端爬取。

2.3 代理問(wèn)題

(1)為什么會(huì)用到代理
(2)代理怎么使用(具體代碼,請(qǐng)求在什么時(shí)候添加的代理)
(3)代理失效了怎么處理

2.4 驗(yàn)證碼處理

(1)登陸驗(yàn)證碼處理
使用tesseract來(lái)識(shí)別,不過(guò)tesseract你要自行去訓(xùn)練它,不然識(shí)別率出奇的低。

(2)爬取速度過(guò)快出現(xiàn)的驗(yàn)證碼處理
(3)如何用機(jī)器識(shí)別驗(yàn)證碼

2.5 模擬登陸問(wèn)題

(1)模擬登陸流程
(2)cookie如何處理
(3)如何處理網(wǎng)站傳參加密的情況

3 數(shù)據(jù)庫(kù)問(wèn)題

3.1 說(shuō)幾個(gè)redis中的數(shù)據(jù)類型和命令

3.2 MySQL中的inner join和left join的區(qū)別 ?

INNER JOIN(內(nèi)連接,或等值連接):取得兩個(gè)表中存在連接匹配關(guān)系的記錄。
LEFT JOIN(左連接):取得左表(table1)完全記錄,即使右表(table2)并無(wú)對(duì)應(yīng)匹配記錄。

  • 擴(kuò)展:RIGHT JOIN(右連接):與 LEFT JOIN 相反,取得右表(table2)完全記錄,即使左表(table1)并無(wú)匹配對(duì)應(yīng)記錄。

4 爬蟲問(wèn)題

4.1 常用的網(wǎng)絡(luò)數(shù)據(jù)爬取方法

正則表達(dá)式,Beautiful Soup, lxml

4.2 設(shè)計(jì)一個(gè)基于session登錄驗(yàn)證的爬蟲方案

5 框架問(wèn)題

5.1 scrapy的基本結(jié)構(gòu)(五個(gè)部分都是什么,請(qǐng)求發(fā)出去的整個(gè)流程)

5.2 scrapy的去重原理 (指紋去重到底是什么原理)

(1)scrapy本身自帶有一個(gè)中間件
(2)scrapy源碼中可以找到一個(gè)dupefilters.py去重器
(3)需要將dont_filter設(shè)置為False開啟去重,默認(rèn)是True,沒(méi)有開啟去重
(4) 對(duì)于每一個(gè)url的請(qǐng)求,調(diào)度器都會(huì)根據(jù)請(qǐng)求得相關(guān)信息加密得到一個(gè)指紋信息,并且將指紋信息和set()集合中的指紋信息進(jìn)行比對(duì),如果set()集合中已經(jīng)存在這個(gè)數(shù)據(jù),就不在將這個(gè)Request放入隊(duì)列中
(5)如果set()集合中沒(méi)有存在這個(gè)加密后的數(shù)據(jù),就將這個(gè)Request對(duì)象放入隊(duì)列中,等待被調(diào)度

5.4 scrapy中間件有幾類,分別在哪里起的作用(面向切面編程)

(1)、scrapy的中間件理論上有三種(Schduler Middleware,Spider Middleware,Downloader Middleware),在應(yīng)用上一般有以下兩種:

1.爬蟲中間件Spider Middleware
主要功能是在爬蟲運(yùn)行過(guò)程中進(jìn)行一些處理.

2.下載器中間件Downloader Middleware
主要功能在請(qǐng)求到網(wǎng)頁(yè)后,頁(yè)面被下載時(shí)進(jìn)行一些處理.

(2)、使用

1.Spider Middleware有以下幾個(gè)函數(shù)被管理:- process_spider_input 接收一個(gè)response對(duì)象并處理,位置是Downloader-->process_spider_input-->Spiders(Downloader和Spiders是scrapy官方結(jié)構(gòu)圖中的組件)- process_spider_exception spider出現(xiàn)的異常時(shí)被調(diào)用- process_spider_output 當(dāng)Spider處理response返回result時(shí),該方法被調(diào)用- process_start_requests 當(dāng)spider發(fā)出請(qǐng)求時(shí),被調(diào)用

位置是Spiders–>process_start_requests–>Scrapy Engine(Scrapy Engine是scrapy官方結(jié)構(gòu)圖中的組件)

2.Downloader Middleware有以下幾個(gè)函數(shù)被管理

- process_request request通過(guò)下載中間件時(shí),該方法被調(diào)用

- process_response 下載結(jié)果經(jīng)過(guò)中間件時(shí)被此方法處理

- process_exception 下載過(guò)程中出現(xiàn)異常時(shí)被調(diào)用

編寫中間件時(shí),需要思考要實(shí)現(xiàn)的功能最適合在那個(gè)過(guò)程處理,就編寫哪個(gè)方法.中間件可以用來(lái)處理請(qǐng)求,處理結(jié)果或者結(jié)合信號(hào)協(xié)調(diào)一些方法的使用等.也可以在原有的爬蟲上添加適應(yīng)項(xiàng)目的其他功能,這一點(diǎn)在擴(kuò)展中編寫也可以達(dá)到目的,實(shí)際上擴(kuò)展更加去耦合化,推薦使用擴(kuò)展.

6 分布式

6.1 分布式原理

這里重要的就是我的隊(duì)列通過(guò)什么維護(hù)?
這里一般我們通過(guò)Redis為維護(hù),Redis,非關(guān)系型數(shù)據(jù)庫(kù),Key-Value形式存儲(chǔ),結(jié)構(gòu)靈活。
并且redis是內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)系統(tǒng),處理速度快,提供隊(duì)列集合等多種存儲(chǔ)結(jié)構(gòu),方便隊(duì)列維護(hù)

如何去重?
這里借助redis的集合,redis提供集合數(shù)據(jù)結(jié)構(gòu),在redis集合中存儲(chǔ)每個(gè)request的指紋
在向request隊(duì)列中加入Request前先驗(yàn)證這個(gè)Request的指紋是否已經(jīng)加入集合中。如果已經(jīng)存在則不添加到request隊(duì)列中,如果不存在,則將request加入到隊(duì)列并將指紋加入集合

如何防止中斷?如果某個(gè)slave因?yàn)樘厥庠蝈礄C(jī),如何解決?
這里是做了啟動(dòng)判斷,在每臺(tái)slave的Scrapy啟動(dòng)的時(shí)候都會(huì)判斷當(dāng)前redis request隊(duì)列是否為空
如果不為空,則從隊(duì)列中獲取下一個(gè)request執(zhí)行爬取。如果為空則重新開始爬取,第一臺(tái)叢集執(zhí)行爬取向隊(duì)列中添加request

如何實(shí)現(xiàn)上述這種架構(gòu)?
這里有一個(gè)scrapy-redis的庫(kù),為我們提供了上述的這些功能
scrapy-redis改寫了Scrapy的調(diào)度器,隊(duì)列等組件,利用他可以方便的實(shí)現(xiàn)Scrapy分布式架構(gòu)

6.2 分布式如何判斷爬蟲已經(jīng)停止了

查一下爬蟲的狀態(tài):

spider.getStatus();//獲取爬蟲狀態(tài)

6.3 分布式去重原理

6.4 分布式爬蟲的實(shí)現(xiàn):

例子1

  • (1).使用兩臺(tái)機(jī)器,一臺(tái)是win10,一臺(tái)是ubuntu16.04,分別在兩臺(tái)機(jī)器上部署scrapy來(lái)進(jìn)行分布式抓取一個(gè)網(wǎng)站.

  • (2).ubuntu16.04的ip地址為39.106.155.194,用來(lái)作為redis的master端,win10的機(jī)器作為slave.

  • (3).master的爬蟲運(yùn)行時(shí)會(huì)把提取到的url封裝成request放到redis中的數(shù)據(jù)庫(kù):“dmoz:requests”,并且從該數(shù)據(jù)庫(kù)中提取request后下載網(wǎng)頁(yè),再把網(wǎng)頁(yè)的內(nèi)容存放到redis的另一個(gè)數(shù)據(jù)庫(kù)中“dmoz:items”.

  • (4).slave從master的redis中取出待抓取的request,下載完網(wǎng)頁(yè)之后就把網(wǎng)頁(yè)的內(nèi)容發(fā)送回master的redis.

  • (5).重復(fù)上面的3和4,直到master的redis中的“dmoz:requests”數(shù)據(jù)庫(kù)為空,再把master的redis中的“dmoz:items”數(shù)據(jù)庫(kù)寫入到mongodb中.

  • (6).master里的reids還有一個(gè)數(shù)據(jù)“dmoz:dupefilter”是用來(lái)存儲(chǔ)抓取過(guò)的url的指紋(使用哈希函數(shù)將url運(yùn)算后的結(jié)果),是防止重復(fù)抓取的.

例子2

參考:https://juejin.im/post/5b0ba020f265da09151f56c7#heading-12

7 模擬登錄

7.1 selenium模擬登錄,遇到驗(yàn)證碼:

截圖,找到驗(yàn)證碼的位置,進(jìn)行識(shí)別

#因?yàn)轵?yàn)證碼不能一次就正確識(shí)別,我加了循環(huán),一直識(shí)別,直到登錄成功
while True:
#清空驗(yàn)證碼輸入框,因?yàn)榭赡芤呀?jīng)識(shí)別過(guò)一次了,里面有之前識(shí)別的錯(cuò)的驗(yàn)證碼
driver.find_element_by_name(“verificationCode”).clear()
# 截圖或驗(yàn)證碼圖片保存地址
screenImg = “H:\screenImg.png”
# 瀏覽器頁(yè)面截屏
driver.get_screenshot_as_file(screenImg)
# 定位驗(yàn)證碼位置及大小
location = driver.find_element_by_name(‘a(chǎn)uthImage’).location
size = driver.find_element_by_name(‘a(chǎn)uthImage’).size
#下面四行我都在后面加了數(shù)字,理論上是不用加的,但是不加我這截的不是驗(yàn)證碼那一塊的圖,可以看保存的截圖,根據(jù)截圖修改截圖位置
left = location[‘x’]+530
top = location[‘y’]+175
right = location[‘x’] + size[‘width’]+553
bottom = location[‘y’] + size[‘height’]+200
# 從文件讀取截圖,截取驗(yàn)證碼位置再次保存
img = Image.open(screenImg).crop((left, top, right, bottom))
#下面對(duì)圖片做了一些處理,能更好識(shí)別一些,相關(guān)處理再百度看吧
img = img.convert(‘RGBA’) # 轉(zhuǎn)換模式:L | RGB
img = img.convert(‘L’) # 轉(zhuǎn)換模式:L | RGB
img = ImageEnhance.Contrast(img) # 增強(qiáng)對(duì)比度
img = img.enhance(2.0) # 增加飽和度
img.save(screenImg)
# 再次讀取識(shí)別驗(yàn)證碼
img = Image.open(screenImg)
code = pytesseract.image_to_string(img)
#打印識(shí)別的驗(yàn)證碼
#print(code.strip())

7.2 tesseract-OCR的在驗(yàn)證碼識(shí)別中的重訓(xùn)練與使用

參考:
https://zhuanlan.zhihu.com/p/40178190

7.3 搭建IP代理池

總結(jié)

以上是生活随笔為你收集整理的python爬虫面试遇到的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。