1. 程式人生 > >Python抓取妹子圖

Python抓取妹子圖

前言

如果你對python爬蟲感興趣,不妨試一下python語言的魅力。

學習一門新的語言怎麼樣才有動力呢,我比較喜歡妹子,如果在我python入門後,想學習下python爬蟲技術,物件如果是一個豐富的妹子圖網站,這是不是一個增益buff呢 [滑稽]

結構目錄

準備

下載python

在開始前我們需要安裝python 2.7 或 python 3.6,前往官網選擇對應系統的版本

下載python

安裝完成後可以在終端下輸入

python --version

輸出 Python 2.7.10 或其他版本說明安裝成功了

安裝requests庫

mac os 安裝pip

如果你使用的mac os系統,並且還沒安裝pip

需要提前pip,同樣是終端下輸入:

sudo easy_install pip

# 省略很多很多,完成後提示下面說明安裝成功了
Using /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg
Processing dependencies for pip
Finished processing dependencies for pip

如有需要可以順便把ipython也安裝了,關於ipython的好處請跳轉
知乎-使用IPython有哪些好處?

sudo pip install ipython

# 省略很多很多,完成後提示下面說明安裝成功了
Successfully installed appnope-0.1.0 decorator-4.0.4 gnureadline-6.3.3 ipython-4.0.0 ipython-genutils-0.1.0 path.py-8.1.2 pexpect-4.0.1 pickleshare-0.5 ptyprocess-0.5 simplegeneric-0.8.1 traitlets-4.0.0

下面開始安裝requests

pip install requests

# 如出現報紅異常,並且有許可權英文,請用
sudo pip install requests

# 安裝完成後,終端下輸出,如果沒有報錯說明安裝成功了
python import requests # 或者你在終端下輸出,顯示所有已安裝庫 pip list

安裝Beautiful Soup 4庫

pip install beautifulsoup4

# 安裝完成後,終端下輸出,如果沒有報錯說明安裝成功了
python
from bs4 import BeautifulSoup

抓取資料

引入第三方庫

import os, re, sys

import requests
from bs4 import BeautifulSoup

說明:
- os 其他作業系統介面,對檔案讀寫
- re 正則表示式語法,如意
- sys 系統特定的引數和功能,改變編碼

爬取指定頁面

@staticmethod
def get_beautiful_soup(url):
    r = requests.get(url)
    if r.status_code == 200:
        html = r.content
        # print(html)
        soup = BeautifulSoup(html, 'html.parser')
        # print(soup.prettify)
        return soup

requests.get(url)獲取物件,然後判斷code
soup = BeautifulSoup(html, 'html.parser')獲取BeautifulSoup物件,第一個引數是html值,第二個是指定的
解析器

建立資料夾

# 建立資料夾
def createFolder(self, folder_path):
    if not os.path.exists(folder_path):
        os.makedirs(folder_path)
        # print('建立檔案目錄成功 ' + folder_path)
    else:
        # print('檔案目錄已存在 ' + folder_path)
        pass
    return folder_path

抓取資料

# 獲取二級目錄名稱
def get_two_level_directory(self):
   soup = self.get_beautiful_soup(self.site_url)
   item = soup.find_all('div', class_='subnav')[0]
   all_string = item.find('span').string
   # 宣告一個數組儲存檔案目錄路徑,建立名稱為 all_folder 的檔案目錄
   folders = [all_string]
   hrefs = [self.site_url]

   all_a = item.find_all('a')
   for a in all_a:
       folders.append(a.string)
       hrefs.append(a.get('href'))
   return folders, hrefs

# 獲取三級目錄
def get_three_level_directory(self, url_path):
    soup = self.get_beautiful_soup(url_path)
    items = soup.find_all('div', class_='pic')[0].find('ul').find_all('li')

    # 宣告一個數組儲存檔案目錄路徑
    folders3 = []
    hrefs3 = []
    for item in items:
        title = item.find('a').find('img').get('alt')
        href_url = item.find('a').get('href')
        folders3.append(title)
        hrefs3.append(href_url)
    return folders3, hrefs3

獲取頁碼

# 獲取總頁碼
    def get_page(self, url):
        soup = self.get_beautiful_soup(url)
        a_list = soup.find_all('div', class_='page')[0].find_all('a')
        max_page = 1
        for a in a_list:
            # 獲取到`a標籤`中的值,然後通過正則判斷是否為整型,返回一個list集合
            pages = re.findall('\d+', a.string)
            # 因為pages集合裡資料編碼格式為utf-8,這裡將它轉換成整型(我在輸出pages時,值為 u'36' 等這樣的資料,所以把集合強制轉換成了int型別)
            pages = [int(pages) for pages in pages if pages]
            # 查詢到最大值,之前用 max(pages)報錯了,,
            for page in pages:
                max_page = max(max_page, page)
        return max_page

抓取圖片地址

# 抓取圖片地址
def get_crawl_data(self, url, max_page, folder_path3):
    for i in range(max_page + 1):
        site_url = url + '/' + str(i)
        soup = self.get_beautiful_soup(site_url)
        item = soup.find_all('div', class_='content')[0].find('a').find('img')
        title = item.get('alt')
        pic_url = item.get('src')
        folder_path = folder_path3 + title + '.jpg'
        # print('{0}  {1}'.format(pic_url, folder_path))
        self.download_pic(pic_url, folder_path)

根據圖片url儲存到本地目錄

# 儲存圖片到本地
@staticmethod
def download_pic(pic_url, pic_path):
    headers = {
        'X-Requested-With': 'XMLHttpRequest',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 '
                      '(KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
        'Referer': "http://www.mmjpg.com"
    }
    try:
        # 設定絕對路徑,資料夾路徑 + 圖片路徑
        if os.path.isfile(pic_path):
            print('該圖片已存在  ' + pic_path)
            return
        print('檔案路徑:' + pic_path + ' 圖片地址:' + pic_url)
        try:
            img = requests.get(pic_url, headers=headers, timeout=10)
            with open(pic_path, 'ab') as f:
                f.write(img.content)
                print(pic_path)
        except Exception as e:
            print(e)
        print "儲存圖片完成"
    except Exception, e:
        print e
        print "儲存圖片失敗: " + pic_url

唯一注意的是18、19、20行

# with 從某種意義上等同
img = requests.get(pic_url, headers=headers, timeout=10)
f = open(pic_path, 'ab')
data = f.write(img.content)
f.close()

open(pic_path, 'ab')
第一個引數是儲存的絕對路徑,第二是檔案模式

模式 描述
r 以只讀方式開啟檔案。檔案的指標將會放在檔案的開頭。這是預設模式。
rb 以二進位制格式開啟一個檔案用於只讀。檔案指標將會放在檔案的開頭。這是預設模式。
r+ 開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
rb+ 以二進位制格式開啟一個檔案用於讀寫。檔案指標將會放在檔案的開頭。
w 開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
wb 以二進位制格式開啟一個檔案只用於寫入。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
w+ 開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
wb+ 以二進位制格式開啟一個檔案用於讀寫。如果該檔案已存在則將其覆蓋。如果該檔案不存在,建立新檔案。
a 開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
ab 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。也就是說,新的內容將會被寫入到已有內容之後。如果該檔案不存在,建立新檔案進行寫入。
a+ 開啟一個檔案用於讀寫。如果該檔案已存在,檔案指標將會放在檔案的結尾。檔案開啟時會是追加模式。如果該檔案不存在,建立新檔案用於讀寫。
ab+ 以二進位制格式開啟一個檔案用於追加。如果該檔案已存在,檔案指標將會放在檔案的結尾。如果該檔案不存在,建立新檔案用於讀寫。

下圖很好的總結了這幾種模式:
這裡寫圖片描述

模式 r r+ w w+ a a+
+ + + +
+ + + + +
建立 + + + +
覆蓋 + +
指標在開始 + + + +
指標在結尾 + +

引用:結構圖和表格來自該網站