很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

煎蛋妹子圖網站

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

正所謂妹子驅動學習,今天就給大家詳細解析下我是如何一步步的完成妹子圖片的抓取。

爬取結果

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

先看下最後的爬取結果,通過運行 demo.py 代碼,程序就會把網站上的妹子圖片,保存到當前工程目錄下。在此程序中我創建了「jiandan」文件夾,並以當前的進度條為新的文件夾名,即「0.0」「1.0」「2.1」等等。最後把爬取到的圖片,保存到相應的文件裡。

程序結構

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

image

程序主要是由 6 個函數組成

  • get_one():是利用 webdriver 來請求對應的網站
  • pares_one():解析沒帶進度條的網站
  • pares_one_of_num():解析有帶進度條的網站
  • write_to_file():把抓取到的圖片保存到本地文件
  • next():進行翻頁
  • main():程序執行的主函數
很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

通過谷歌瀏覽器的開發者模式可以看到,網站的返回結果裡是一堆 html 代碼,但並沒有我們想要的圖片鏈接信息。如果你用常規的 requests 進行請求,返回的數據是不會有我們想要的圖片信息。

所以這裡我就想到,網站的圖片資源應該是通過 js 加載的。對於需要 js 才能加載出來的網站,我們就可以利用 selenium 自動化測試請求庫來進行加載。通過 selenium 請求庫,我們就可以模擬一個真實的瀏覽器,請求網站,加載 js,返回我們想要的數據。這裡對應的代碼如下,需要你去網上下載對應的 chrome 驅動。

browser = webdriver.Chrome()# 設置網站等待時間wait = WebDriverWait(browser, 10)

圖片信息提取

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

這裡需要注意的是,我最開始在爬取的過程中遇到有些圖片不是 jpg 格式,以及有些圖片是 gif 格式。所以我加了一些判斷來保證,獲取到的圖片鏈接是 jpg 格式,程序才能把圖片下載下來。所以這裡就有優化的地方,大家可以去再查找一些資料,看看是否可以把 png 或 gif 格式的圖片一起保存。

解析源代碼

當前進度條

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

為了控制程序爬取的次數,我們就需要找到一些條件來進行判斷。一般的網站是會返回總的條數,但這次的網站通過觀察並沒有返回總條數的信息。並且在最開始進入妹子圖板塊,上方是沒有進度條信息。

但當點擊下一頁的時候,網站就有顯示出當前的進度條。

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

我們就可以利用這個當前瀏覽的位置,來控制程序爬取的次數。隨後通過網站的源代碼分析,就很容易得到這部分的信息,對應的代碼如下:

num = soup.select('#body #comments .comments .page-meter-title')[0].getText()percent = re.findall('\d+', num)percent_num = percent[0] + '.' + percent[1]

然後定義一個 next() 函數,來判斷當前的進度條是否達到 100.0%,如果沒有則繼續爬取,對應的代碼如下:

def next(url): html = get_one(url) percent_num, next_url = pares_one_of_num(html) while percent_num != '100.0': next(next_url) 

下一頁鏈接

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

很多人學爬蟲的目的,應該都和小編一樣!終於會爬煎蛋網的妹子了

def pares_one(html): soup = BeautifulSoup(html, 'lxml') imgs = soup.select('img') url = soup.select('#body #comments .comments .cp-pagenavi a')[1] href = re.findall('href="(.*?)"', str(url)) next_url = 'https:' + href[0] count = 0 for img in imgs: img_url = re.findall('class="lazy" data-original="(.*?)"', str(img)) if not img_url[0][-3:] == 'gif': if not img_url[0][-3:] == 'png': print('正在下載:%s 第 %s 張' % (img_url[0], count)) write_fo_file(img_url[0], '0.0', count) count += 1 return next_urldef pares_one_of_num(html): soup = BeautifulSoup(html, 'lxml') imgs = soup.select('img') num = soup.select('#body #comments .comments .page-meter-title')[0].getText() percent = re.findall('\d+', num) url = soup.select('#body #comments .comments .cp-pagenavi a')[1] href = re.findall('href="(.*?)"', str(url)) percent_num = percent[0] + '.' + percent[1] next_url = 'https:' + href[0] count = 0 for img in imgs: img_url = re.findall('class="lazy" data-original="(.*?)"', str(img)) if not img_url[0][-3:] == 'gif': if not img_url[0][-3:] == 'png': if img_url[0][-3:]: print('正在下載:%s 第 %s 張' % (img_url[0], count)) write_fo_file(img_url[0], percent_num, count) count += 1 return percent_num, next_url

保存數據

最後就是把圖片保存到文件中,這部分的代碼如下:

def write_fo_file(url, num, count): dirName = u'{}/{}'.format('jiandan', num) if not os.path.exists(dirName): os.makedirs(dirName) filename = '%s/%s/%s.jpg' % (os.path.abspath('.'), dirName, count) print(filename) with open(filename, 'wb+') as jpg: jpg.write(requests.get(url).content)

優化改進

image

本次的程序還有一些不足的地方,比如利用 selenium 庫在解析的時候非常的慢,這部分是可以優化的。還有程序在爬取到 80.6% 的時候,程序報錯了,並沒能把圖片全部爬取完。這就說明還有一些情況,我沒有考慮到。有待以後進一步優化。


分享到:


相關文章: