Python爬取周杰倫instagram

冰山劉發表於2018-07-08

整體框架

使用國內能訪問的某國外 app angine 爬取Jay的 Instagram 並顯示,再使用國內的 sae 訪問這個網站,再爬取一次併傳送到微博小號。

bs4

使用requests爬取 Instagram 時候,並沒有加request header,Instagram 對 robot 還算友好,直接返回不帶 js 的網頁資訊。通過bs4迅速定位到照片、視訊資訊,再用正規表示式提取到連結並下載、顯示。,正規表示式讓人頭痛,使用str.split(` `)來使字串變成列表。

from bs4 import  BeautifulSoup

filepath = `C:UsershndxDesktopins.html`
soup = BeautifulSoup(open(filepath),`lxml`)

script = soup.select(`script`)

print str(script[2]).split(`},{"node":`)[1]

通過分析ins.html,得到每個node就是一個動態。這樣str(script[2]).split(`},{"node":`)[1]就是帶有Jay最新動態資訊的 Unicode 字元了。應用json 直接將這個資訊轉化成字典dict,如下

import json
i = json.loads(info)
print i["edge_media_to_caption"][`edges`]
"""
[{u`node`: {u`text`: u`Just finished now u8b1du8b1du91d1u83efu7684u670bu53cbu5011 highu7684u4e0du8981u4e0du8981u7684 #u91d1u83ef #u96d9u7bc0u68cd#u96d9u622au68cd`}}]
"""

儲存圖片

參考 :如何用requests優雅的下載圖片? ,這個應該是最簡潔的答案了。

import requests
s = requests.session()
ss = s.get(`https://www.baidu.com/img/bd_logo1.png`)
open(`logo.png`, `wb`).write(ss.content)

資料庫 ORM Flask-SQLAlchemy

學習參考 Flask-SQLAlchemy 官方文件
有關增刪改查的操作 flask SQLAlchemy 資料庫操作
資料庫物件

class photo(db.Model):
    __tablename__ = "photoid"

    id = db.Column(db.Integer)  #引數  primary_key=True 表示此鍵值不能重複,必須有一個primary_key=True。
    url = db.Column(db.String(4096),primary_key=True )
    text = db.Column(db.String(4096))

    def __init__(self, id, url,text):
        self.id = id
        self.url = url
        self.text = text #這裡有三個行

關於建立、查詢


In [1]: import flask_app

In [2]: con = [`1`,`2`]

In [3]: flask_app.photo(con[0],con[1])
Out[3]: <flask_app.photo at 0x7fa109b5ccd0>

In [4]: flask_app.db.session.add(flask_app.photo(con[0],con[1]))

In [5]: flask_app.db.session.commit()

In [6]: flask_app.photo.query.filter_by(id=`1`).first()
Out[6]: <flask_app.photo at 0x7fa11179e890>

In [7]: p1 =flask_app.photo.query.filter_by(id=`1`).first()

In [8]: p1.id
Out[8]: 1

In [9]: p1.url
Out[9]: u`2`

Mysql 用到的語句

DROP TABLE table_name ;

刪除資料表

insta.py

# -*- coding: utf-8 -*-
"""
insta 爬蟲
Created on Fri May 04 09:02:26 2018

@author: aubucuo
"""
import requests
from json import loads
from bs4 import  BeautifulSoup
import re

s = requests.session()
u = `https://www.instagram.com/jaychou/`

def ins(pid):
    rt = []
    c1 = s.get(u)
    soup = BeautifulSoup(c1.content,`lxml`)
    script = soup.select(`script`)

    ls = script[2].contents
    ls1 = re.findall(`window._sharedData = (.+?);`, str(ls[0]))
    js = loads(ls1[0])[`entry_data`][`ProfilePage`][0][`graphql`][`user`][`edge_owner_to_timeline_media`][`edges`]
    j_id = js[0][`node`][`id`]
    is_video =js[0][`node`][`is_video`]
    j_url = js[0][`node`][`display_url`]
    j_text = js[0][`node`][`edge_media_to_caption`][`edges`][0][`node`][`text`]


    if j_id!= pid and not is_video: #如果id 不重複 且不是video
        rt.append(True)
        rt.append(j_id)
        rt.append(j_url)
        rt.append(j_text)

        c2 = s.get(j_url)
        open(`mysite/static/jay.jpg`, `wb`).write(c2.content)
        return rt
    else :
        rt.append(False)
        return rt

其中pid上次執行時候最新一張圖片的id,用來判斷是否有更新。其實這裡bs4對我的幫助並不大。上面程式只做到了儲存最新的一張圖片(jay.jpg),實測中,總是儲存第二張圖片,可能是正規表示式的問題。不影響功能,不再深究了。
使用 json 精準定位N次,(注意到js變數)

發微博參見 微博API 學習記錄


相關文章