用Python編寫一個簡單的爬蟲

做者信息:html

Author : 黃志成(小黃)

博客地址: 博客vue

吶,這是一篇福利教程.爲何這麼說呢.咱們要爬取的內容是美圖網站(嘿嘿,老司機都懂的)mysql

廢話很少說.開始今天的表演.web

這個圖集網站不要問我怎麼來的.絕對不是我刻意找的.(實際上是看了別的發的一篇文章,就想本身動手實現一下)redis

咱們今天的任務就是 將這些圖集保存下來。sql

首先咱們須要獲取到全部的列表,咱們往下拉動滾動條,拉到底,會繼續自動加載內容,咱們經過瀏覽器的NetWork能夠發現請求的數據包json

咱們來分析一下這個數據包瀏覽器

URL:https://www.toutiao.com/search_content/?offset=0&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=20&cur_tab=3&from=gallery

經過url咱們能夠知道幾個重要的參數多線程

offset 偏移量
count 數量
cur_tab 當前分類

這裏不少朋友可能對偏移量不太瞭解,這裏我用sql語句表示一下,若是瞭解sql的朋友 確定就知道了函數

mysql> SELECT * FROM art LIMIT offset , count

mysql> SELECT * FROM table LIMIT 5,10;  // 檢索記錄行 6-15

mysql> SELECT * FROM table LIMIT 95,1; // 檢索記錄行 96

這裏我每次讀取一條,對一條進行操做.

URL:https://www.toutiao.com/search_content/?offset=1&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=1&cur_tab=3&from=gallery

每次對offset 進行自增便可了

咱們點擊進去 看看數據的結構.

咱們須要獲取到該圖集的連接。

進入這篇圖集,在NetWork中並無發現圖集有關的請求接口,可能也是混排的.

咱們能夠查看頁面的源碼

原來真的是混排的寫法.看了一下這裏用到vue.具體怎麼實現的咱們不去探討了,咱們只須要取出數據便可。

那如何取出呢? 提供兩種方法,一種就是正則,一種就是本身寫一個取文本的函數.這裏我用第二種做爲演示,下面是取文本的函數.

def txt_wrap_by(start_str, end, html):
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()

咱們取出 JSON.parse("") 中的數據

觀察數據,能夠發現 咱們取出 url 就能夠了,這裏的數據是json可是被轉義了,咱們就經過正則取出吧

正則的語法如圖上,最後我也會放出全部代碼滴,你們放心.

取到了uri 咱們只要在前面拼上 http://p3.pstatp.com/ 便可.

而後保存爲圖片便可~

上面說的都是思路,最後放出代碼~

import requests,os,json,re,datetime

# 主函數
def main():
    foreach_art_list()

def foreach_art_list():
    # 判斷目錄下是否存在jilv.txt文件 若是存在則讀取裏面的數值
    if os.path.exists('./jilv.txt'):
        f = open('./jilv.txt')
        n = f.read()
        n = int(n)
        f.close()
    else:
        n = 1    
    while True:
        url = 'http://www.toutiao.com/search_content/?offset=' + str(n) + '&format=json&keyword=%E6%B8%85%E7%BA%AF%E7%BE%8E%E5%A5%B3&autoload=true&count=1&cur_tab=3&from=gallery'
        re = requests.get(url)
        data = re.json()['data']
        if not data:
            break
        # 運行圖片下載函數
        download_pic(data[0]['article_url'],n)
        n = n+1
        # 將n寫入文件 防止程序運行出錯 能夠繼續運行
        with open('./jilv.txt', 'w') as f:
            f.write(str(n))

def download_pic(url,n):
    download_pic_url = 'http://p3.pstatp.com/'
    # 這裏必須帶上協議頭,不然會請求失敗
    header = {
        'user-agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36'
    }
    res = requests.get(url,headers = header)
    content = res.text
    img_list_json = txt_wrap_by('gallery: JSON.parse("','"),',content)
    # 正則獲取全部的uri
    img_list = re.findall(r'uri\\":\\"(.*?)\\"',img_list_json)
    #判斷是否有此目錄
    if 'img' not in os.listdir('.'):
        os.mkdir('./img')
    if str(n) not in os.listdir('./img'):
        os.mkdir('./img/'+str(n))
    for v in img_list:
        img_path = download_pic_url + v
        img_path = img_path.replace("\\", "")
        # 讀取圖片
        atlas = requests.get(img_path).content
        # 保存圖片
        with open( './img/' + str(n) + '/' + str(datetime.datetime.now()) +'.jpg', 'wb') as f:  # 把圖片寫入文件內
            f.write(atlas)


# 取出兩個文本之間的內容
def txt_wrap_by(start_str, end, html):
    start = html.find(start_str)
    if start >= 0:
        start += len(start_str)
        end = html.find(end, start)
        if end >= 0:
            return html[start:end].strip()

# 運行程序
main()

最後 展現一下 運行結果:

這個程序還有許多不完善的地方,我會在以後教程加入 redis 和 多線程 的寫法,讓他成爲最快的爬蟲~

敬請期待~ 今天就到這裏了. 又是週末!祝你們週末愉快。嘿嘿~ 看個人美圖去了。

相關文章
相關標籤/搜索