Python網頁篇:Django- 初始環境

現在開始來講用python開發網頁,
這一篇到後面幾篇來講講用Django 架設一個用markdown寫作的部落格。

也藉著這個範例來說明一下django.

首先,當然是要先安裝好django啦!

pip install django

然後要創建一個django的專案請使用

django-admin startproject {專案名稱}
#我這裡就是專案名稱為blog
django-admin startproject blog

你的資料夾結構如下

blog
├── blog
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

接下來到blog的資料夾(或者你專案的資料夾下),使用

python manage.py runserver

接下來會出現一個網址,像我的訊息就是

Performing system checks...

System check identified no issues (0 silenced).

You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

October 24, 2018 - 14:12:00
Django version 2.1.2, using settings 'blog.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

接下來你只要在瀏覽器key上http://127.0.0.1:8000/ 就看到django的初始頁啦
接下來我們一起好好研究Django吧!

Python 走入現實:json

今天來講怎麼用python怎麼讀取json.

json 是一個資料表示的型式。
以範例來看:

import json

# json 的資料形式字串
x =  '{ "name":"jim", "age":25, "city":"Taiwan"}'

# 轉換json
person = json.loads(x)

print(type(person)) #<class 'dict'>
print(person){'name': 'jim', 'age': 25, 'city': 'Taiwan'}
print(person['age']) #25

要讀取json非常簡單,import json這個module
然後經由loads這個方法轉出,會產生一個dictionary型態資料

接下來,是反過來~把python的物件轉換成json,則使用dumps方法

import json

person = {'name': 'jim', 'age': 25, 'city': 'Taiwan'}

data = json.dumps(person)

print(type(data)) #<class 'str'>
print(data) #{"name": "jim", "age": 25, "city": "Taiwan"}

Python 走入現實:selenium+爬蟲

昨天介紹了selenium 這個module
今天來加強版,讓selenium 和beautifulSoup結合為一

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup

url ='https://tw.yahoo.com/'

#今天講個特別的,我們可以不讓瀏覽器執行在前景,而是在背景執行(不讓我們肉眼看得見)
#如以下宣告 options
options = webdriver.ChromeOptions()
options.add_argument('--headless')

#打開瀏覽器,確保你已經有chromedriver在你的目錄下
# 然後將options加入Chrome方法裡面,至於driver請用executable_path宣告進入
browser=webdriver.Chrome(chrome_options=options, executable_path='./chromedriver')
#在瀏覽器打上網址連入
browser.get(url) 

#這時候就可以分析網頁裡面的元素
element = browser.find_element_by_id('UHSearchBox')
element.send_keys('Hello World')

sumbit = browser.find_element_by_id('UHSearchWeb').click()

# 等待目標表格'id 為 web'的div出現
element = WebDriverWait(browser, 5).until(
    expected_conditions.presence_of_element_located((By.ID, 'web'))
)

#然後就是beautifulsoup的範疇了,將browser.page_source放進去分析
soup=BeautifulSoup(browser.page_source,"html.parser")
links = soup.select('div#web h3')

for link in links:
    print(link.get_text())

browser.quit()

接下來就會印出 yahoo搜尋 hello world的搜尋結果標題們了,撒花~~

Python 走入現實:selenium

今天來介紹一個特別的module: selenium
他是一個可以控制瀏覽器的module.

但如果你要控制瀏覽器載入這個module以外也要在下載相對應瀏覽器的driver還有相對應作業系統的版本,

我這裡以我自己作業系統為mac os 還有 瀏覽器的driver設定為我個人最常用的‘chrome’為例
如果你是其他os或者要弄其他的瀏覽器,請造訪
https://selenium-python.readthedocs.io/installation.html

啊如果還是看不懂歡迎在底下留言討論。

先上範例程式碼:
這裏我是用yahoo的網址然後在搜尋框打上hello world 並且做搜尋

from selenium import webdriver

url ='https://tw.yahoo.com/'

#打開瀏覽器,確保你已經有chromedriver在你的目錄下
browser=webdriver.Chrome('./chromedriver')
#在瀏覽器打上網址連入
browser.get(url) 

#這時候就可以分析網頁裡面的元素
element = browser.find_element_by_id('UHSearchBox')
element.send_keys('Hello World')

sumbit = browser.find_element_by_id('UHSearchWeb').click() 

關於selenium 你可以更多看文件:
https://selenium-python.readthedocs.io/index.html

接下來執行你就會很清楚的發現電腦另立一個新的chrome,然後坐著我們想要做的事…

這樣的工作可以做什麼?可以延伸什麼?
1.表單填寫:例如如果電子連署我可以大量搞死人連署(大誤XD
2.軟體工程師的網頁測試
3.可以和beautifulsoup搭配,天底下已沒有你爬不到的資料XD
4.其他你覺得用瀏覽器很麻煩的動作

Python 走入現實:來爬蟲吧(3)

昨天看到一個大大po 鐵人賽的文章。
終於解決了如何提取圖片的問題,原來,request也是可以讀到圖片檔的資訊的

來吧! 我們來學習如何爬圖片!
其實網頁要呈現圖片有幾個方向

  1. img 標籤
  2. css image 相關的屬性
  3. 用js 放進去(但不太可能有人做這種事情…除非是互動性太高需要換圖片的那種)

img 標籤要爬最簡單,看看src標籤就可以囉~ css的話就會比較麻煩一點
總之,爬蟲前是要做一些功課的,他是一種極客製化的一種功能

這時就要說一下自己的切身之痛
我很久以前也在下班時間玩python的時候寫關於爬蟲的東西,結果不知道最近是不是網頁改版抑或是python函式庫的問題,總之這個在去年還是前年寫的馬上出錯,怎麼debug都不對…..怎麼google解法都解決不了

這時候你要去想辦法尋找解法,
1)是繼續在這個錯誤當中繞圈,跟他死嗑到底(想辦法正面和這個錯誤衝突)?
2)尋找替代方案? (和小學生一樣抄隔壁的作弊XD)
3)如果是接案或者那種有客戶你還有第三種選擇:說服他不要做這個功能(逃避隨可恥但有用?!!!!!!)

因為網路上其實很多人都有在寫python抓圖片的程式或api ,你要相信一句話:你不是第一個發生這個問題的人

我和這個錯誤正面處理已經很久了,所以顯然第一個解法是不適合的,又或者等等寫完這篇鐵人賽或鐵人賽結束我會繼續想辦法解決這個錯誤,所以最後我來參考其他人的程式碼來看看他們怎麼抓圖片。

這時候,你有看懂python程式的功力很重要,如何將他人的程式碼擷取或者看懂邏輯進而應用到自己的程式碼是一門藝術,我自己也還在摸索學習。

話不多說,上菜了,以爬https://www.inside.com.tw/ 為例
如果你要爬其他網站,可以自行分析,或者歡迎在底下留言和我討論XD 我做不到我會google哈哈哈

分析一下inside的網頁,在他上方的slider 程式碼有段敘述
如果你頑皮一點將url 裡面的網址貼上瀏覽器, yo 圖片get!

<ul class="hero_slides">
    <li class="hero_slide js-hero_slide" style="background-image: url(https://www.inside.com.tw/wp-content/uploads/2018/10/RTX2Z7S8.jpg)">

所以接下來爬蟲囉! 不知道inside 會不會吉我?哎呦 別這樣 你們如果改版的恐怕我底下的程式碼直接廢掉XD
「同是工程師,相煎何太急」

這裏也要呼籲,爬蟲請務必遵守法律規範,因為網頁上的圖片是公開的,而且基本上我也沒要拿來幹嘛。所以我是合法使用(應該吧???!)

以下程式碼我是來抓inside 最上面slider 的幾張圖片,並且為了整齊將這些圖片都放到images這個資料夾裡

import requests
from bs4 import BeautifulSoup
import os
import re

url="https://www.inside.com.tw/"

request=requests.get(url)
content=request.content
soup=BeautifulSoup(content,"html.parser")

container = soup.select("li.hero_slide")

# print(container)
dirname = 'images'
'''
這裡介紹一個module 是os ,如果要學習更多歡迎到這裡:https://kaiching.org/pydoing/py/python-library-ospath.html
'''
# 如果沒有images 資料夾會出錯,所以這裡我會判斷有沒有這個資料夾如果沒有就建立
# 請注意是'not' os.path.isdir 是判斷這個資料存在回傳true :不存在是false ,如果不存在就要建立資料夾,為了要讓條件成立你必須加上not,not false 就是true ,就會進入到os.mkdir的環節
if not os.path.isdir(dirname): 
        os.mkdir(dirname)

for item in container:
    if item:
        # print(type(item)) #debug 用,來看看到底輸出是否是預期的結果
        value = item['style']
        # 這裏我用之前的正規表達式提取文字
        # item['style'] => background-image: url(https://www.inside.com.tw/wp-content/uploads/2018/10/RTX2Z7S8.jpg)
        # 但我只要url括弧內的網址。
        img_url = re.findall(r"\((.+?)\)",value)
        # 藉由re.findall出來的是list 所以這裏我宣告找第一個,也就是只有一個
        img_url = img_url[0]
        # print(img_url) #debug 用,來看看到底輸出是否是預期的結果
        # 這裏的檔案名稱你可以選擇其他命名方式,我這裡是選擇擷取他在網頁上的檔名
        # example: 如果是https://www.inside.com.tw/wp-content/uploads/2018/10/RTX2Z7S8.jpg 我就擷取到RTX2Z7S8.jpg 為檔名
        filename = img_url.split('/')[-1]
        
        #再發出一個request,然後建立檔案把編碼寫入檔案中
        pic=requests.get(img_url)
        imgcontent = pic.content
        #這裏os.path.join 其實你也可以改成 dirname+'/'+filename 啦
        image = open(os.path.join(dirname,filename),'wb')
        image.write(imgcontent)
        image.close()
        # break #debug 用,來看看到底輸出是否是預期的結果

Python 走入現實:圖形化介面

哈! 結果到現在十點多才回到家
沒有研究到多媒體資源到底該如何提取爬蟲過來,抱歉! 趁著週末時間來好好研究,希望可以明天和大家分享一下怎麼爬多媒體資源(又或者鐵人賽之前吧?!趕不上的話….我不會學世堅跳海,只會和大家說聲抱歉啦哈)

這裏再用圖形化介面幫我代打啊哈
這裏我使用的圖形化介面module是tkinter。

你會發現,原來python這麼簡單!!!

import tkinter as tk #哎這也是一種遺珠之憾,module也可以用別名,使用as加入你想改的名字也可以喔

root = tk.Tk()
root.title('Hello World Application') #介面的標題是'Hello World Application'

root.mainloop()

只要import tkinter這個module, 接下來請呼叫他的Tk()方法
記得,最後的mainloop方法也要,這樣你就呼叫出一個圖形化介面囉!

當然啦,只是這樣我這篇也太偷懶了XD
昨天都這麼偷懶今天怎麼可以還這樣呢(昨天偷懶真的不是故意的啊!差點要熬夜隔天爬不起來上班啊)

所以,我來做一個可以按下按鈕,呼叫‘Hello World’訊息框的應用範例吧!

import tkinter as tk
import tkinter.messagebox as messagebox

def HelloWorldMsgBox():
    print('hello world')
    messagebox.showinfo("Hello World Application", "Hello World!") #呼叫hello world的訊息框

root = tk.Tk()
root.title('Hello World Application')

buttonHelloWorld = tk.Button(root, text='SayHello', width=25, command=HelloWorldMsgBox)
buttonHelloWorld.pack() #按下去啟動上面定義好的HelloWorldMsgBox方法

buttonClose = tk.Button(root, text='Close', width=25, command=root.destroy)
buttonClose.pack() #按下去啟動root.destroy,也就是關閉視窗
root.mainloop()

其實你只要會google,把tkinter的元件叫出來就好,所以這裡我宣告了兩個button,一個是跳出提示窗hello world,另外一個則是關閉視窗。

然後每個元件記得也要加入pack方法喔~就像最後的mainloop一樣

如果要出現提示窗請引入tkinter的messagebox,然後就可以調用了,當我們在button裡面command屬性宣告等於我們某個方法名稱,你就可以使用囉!

若要學習更多tkinter請到此:
https://www.python-course.eu/python_tkinter.php
https://pythonspot.com/tk-window-and-button/

Python 走入現實:正規表達式

不好意思發現要爬蟲多媒體資源時發現一些問題,目前還在debug中哈哈…

以後再來試試看怎麼取獲取多媒體資源,我承諾在鐵人賽結束前一定會想辦法生出來,
今天為了能夠完成這一天先以正規表達式代打
真是不好意思了。

在python中用正規表達式非常簡單,就是用’re’這個module

import re

string = 'Hello World'
relist = re.findall(r"[a-z]*",string)
print(relist)

這樣你就會求出a-z 的文字喔。

正規表達式對於我們在搜尋或者分析資料非常好用
提供一些可以參考的資料:

https://regex101.com/
http://ju.outofmemory.cn/entry/71121

Python 走入現實:來爬蟲吧(2)

前一天我們談到如何使用python發出類似瀏覽器的request,把所要的HTML+CSS+JS都給他抓過來。
但是如果只是這樣那爬蟲又有什麼多厲害呢? 爬蟲的厲害之處就是能把抓回來的東西,拿出來好好的分析,藉此獲得我們想要的資訊或者有用的資訊

因此,讓我接下來為他介紹收到request之後的事情吧!

BeautifulSoup

其實python有許多的爬蟲套件,我之前個人下班在玩的時候都是用這個套件,當然也有其他可以爬的套件。
這裏我介紹某位youtuber的資源:https://www.youtube.com/watch?v=T2xNeWutlcA

厲害吧!他居然用python爬蟲去抓成人影片!呵呵 不過他用的是另外一種module 叫做pyquery

好啦,確定你有安裝好beautifulSoup之後就來開始吧
這裡就不抓成人影片了,我們先開始抓取‘文字內容’,明天再來講我們怎麼抓取非文字內容的資料。
我們來抓youtube今天熱門影片的標題們XD

大家都知道:youtube的熱門影片網址是:https://www.youtube.com/feed/trending

import requests;
from bs4 import BeautifulSoup;

url="https://www.youtube.com/feed/trending/"

request=requests.get(url)
content=request.content
soup=BeautifulSoup(content,"html.parser")

container = soup.select("h3 a")

# print(type(container))
# print(container)
# 接下來只是寫入result.txt檔案的事情
file = open('result.text','w')

for item in container:
    if item:
        #print(type(item))
        value = item.get_text()
        print(value)
        file.write(value+'\n')
        #break #這裡也提一個起手式的遺珠之憾,就是你可以用continue和break來處理 迴圈敘述,這裏為了我之前debug方便,使用break來讓我先只看一個的結果。
        

file.close()

用範例講解:
首先先把兩個module beautifulsoup &request引入
接下來你會看到我使用request.get 取得熱門影片的youtube網頁的內容。
再來你就用soup=BeautifulSoup(content,"html.parser")
把content 丟入beautifulSoup解析,後面參數記得加上‘html.parser’

然後回去用瀏覽器打開https://www.youtube.com/feed/trending/ 這個網頁,可能希望你會有一些基礎的html+css基礎,總之你可以仔細看看每個標題的地方,上面都會有h3 以及我們最想要的標題文字正好都被包在a這裡面。

所以我們可以使用container = soup.select(“h3 a”) 來把所有的標題提出來。
接下來只是寫入result.txt檔案的事情了

1.你可以先print(container)和print(type(container)): 你會發現他是<class ‘list’> ,所以你知道了吧!他就是個list,所以後面我用迴圈把他一一提取出來。
2.進入迴圈後如果你還是很好奇,可以用print(type(item))看看:他是<class ‘bs4.element.Tag’>,所以後面我可以用get_text()這個方法取出他的標題文字。

關於beautifulsoup還有很多可以在教學或更多運用的,這裏我附上我debug參考的一些網址

更多BeautifulSoup教學: https://www.dataquest.io/blog/web-scraping-tutorial-python/

明天我將試看看爬多媒體資源看看!敬請期待!

Python 走入現實:來爬蟲吧(1)

剛剛在想今天要寫什麼的時候….突然想到之前其實就有點想寫爬蟲的主題XD
所以就來寫一波!

淺談網路與網頁

其實我們藉由瀏覽器打入網址看到的“網頁”,獲得的都是一種“資源”,而這個資源他所回傳的是HTML+CSS+JS(當然對於‘api’來說,他有可能回傳的是’json’、’xml‘或者其他類型)。其實說穿了網頁前端說難不難說雜不雜,就是基於這三大天王。當然你會問,那麼我們常說的後端語言:php、ruby、或者是現在我們在談的python呢?我們總不可能拿前端來連資料庫吧(安全緣故)?沒錯! 對於開發者的角度來說,我們是用這些後端語言,但如果你發現,其實後端語言都是會由CGI或者後端渲染的引擎,當你試著對網頁開啟右鍵檢查時,他還是HTML+CSS+JS啊!

這裏還只是淺談,如果要繼續深入的話可以說非常非常多,預計30天鐵人賽都寫不完,這裏我極力推薦某個部落客寫的有關於http的文章以及一些我個人覺得可以更加深入的參考資料,淺顯明瞭、而且我也是讀過了對於網路、瀏覽器有更多的認識呢!

  1. NotFalse 技術客所寫的http教學系列
    https://notfalse.net/http-series
  2. 來做個網路瀏覽器吧!Let’s build a web browser! 系列:去年某大大寫的鐵人賽系列,看不懂沒關係,我也看不是太懂XD 但前面幾篇文章多少對於瀏覽器如何運作或者網路如何操作會有更多的了解
    https://ithelp.ithome.com.tw/users/20103745/ironman/1270
  3. 維基或者google: 當然你也可以用wiki或自行google來幫助自己更加了解
    https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

總之,我們可以知道我們爬回來的東西就是一連串的文字,就是HTML+CSS+JS/除非你是對API 當然就獲得其他類型的資料

環境建置

如果你不喜歡自己的環境太過髒亂,你想要有‘vitual’ 環境,那非常好,python3自己有內建,另外我自己或網路上也推薦‘virtualenv’這個modules

如果想了解更多歡迎來到我自己的技術部落格。
https://tech.r567tw.tw/python_virtualenv-%e7%b0%a1%e5%96%ae%e7%ad%86%e8%a8%98/

總之,時間不多 let’s start!
我就先假設大家想要有一個不受污染的環境吧
先確定安裝好pip之後請執行

pip install virtualenv #安裝virtualenv這個環境
virtualenv crawler #建立一個名字叫做crawler的虛擬環境
source crawler/bin/activate #啟動這個crawler 這個環境(for mac)
\crawler\Scripts\activate.bat #或者也可以執行這個指令 (for windows) [參考](https://programwithus.com/learn-to-code/Pip-and-virtualenv-on-Windows/)

你的環境如果有啟動的話應該可以看到你們前面會有個類似‘(crawler)’的字樣。
要離開的話就使用’deactivate’這個指令吧!
在虛擬環境之下/或者直接本機
請安裝幾個會需要用到爬蟲的module吧!

pip install requests #安裝一個可以發出網路request的module
pip install BeautifulSoup4 #可以用這個module分析回傳回來的html+css+js

牛刀小試一下

在想要不要一口氣談完爬蟲的同時我發現時間很晚了,所以就只好分個幾天慢慢說明好了。
前面說到我們的爬蟲通常會拿回來HTML+CSS+JS,那我們就來驗證一下吧!
建立crawler.py

import requests;
from bs4 import BeautifulSoup;

url="https://tw.yahoo.com/"

request=requests.get(url)
content=request.content

print(content)

執行後你看到了什麼呢?
是不是html+css+js呢?

或者你也可以使用

print(type(content))

回傳了‘<class ‘bytes’>’
bytes就是檔案的最小單位。

如果還是很好奇我說的回傳的html+css+js (因為print出來有什麼x開頭的亂碼)
那麼我們試著把回傳回來的bytes 轉成string 寫入檔案中,我們可以這樣改寫:

import requests;
from bs4 import BeautifulSoup;

url="https://tw.yahoo.com/"

request=requests.get(url)
content=request.content

file = open('result.txt','w')
file.write(content.decode('utf-8'))

執行後看看result.txt是不是就是網站的html+css+js呢?

如果你今天頑皮一點把result.txt改為result.html呢?
哈哈! 打開result.html就是“很像”的yahoo首頁啦~~ XD 但應該是不能work的首頁啦,畢竟你只是copy前端,yahoo的背後還有很多眉眉角角呢(我們剛剛談到的後端開發語言或資料庫或圖片等等)

Python 走入現實:檔案

恩…想不到什麼更好聽的標題名稱了哈哈,總之接下來要介紹一些可以在實際操作的內容。
今天來講講怎麼做一個檔案以及怎麼去讀檔好了。

首先,讀檔的範例如下:

f = open("hello.txt","r") #open 的第二個參數至關重要,之後我會再繼續說明,r這個參數就是檔案是唯讀的
print(f.read()) #這是讀全部內容的
print(f.read(10)) #讀前面幾個文字

請注意你執行這個python檔案的目錄,然後確認這個目錄底下使否有hello.txt的檔案。
這樣就會把資料讀出來。

另外,寫檔或者建檔的程式範例如下

f = open("demo.txt", "a") #a 這個參數就是附加檔案內容,檔案不管存在不存在
f.write("Now the file has one more line!")

之後你就會在目錄下找到demo.txt這個檔案,然後就會看到這個內容。
除了“a” 以外也可以用“x”或“w”, 前者是file“必須不存在”,加入x這個參數就會幫你建立這個檔案。而w這個參數就會不管這個檔案存不存在,就會把原本的內容全部重洗掉然後加入。