主頁 > 後端開發 > 06-python爬蟲庫urllib,開始撰寫python爬蟲代碼

06-python爬蟲庫urllib,開始撰寫python爬蟲代碼

2020-10-11 14:36:09 後端開發

終于要開始寫爬蟲代碼了

我們首先了解一下 Urllib 庫,它是 Python 內置的 HTTP 請求庫,也就是說我們不需要額外安裝即可使用,它包含四個模塊:

第一個模塊 request,它是最基本的 HTTP 請求模塊,我們可以用它來模擬發送一請求,就像在瀏覽器里輸入網址然后敲擊回車一樣,只需要給庫方法傳入 URL 還有額外的引數,就可以模擬實作這個程序了,

第二個 error 模塊即例外處理模塊,如果出現請求錯誤,我們可以捕獲這些例外,然后進行重試或其他操作保證程式不會意外終止,

第三個 parse 模塊是一個工具模塊,提供了許多 URL 處理方法,比如拆分、決議、合并等等的方法,

第四個模塊是 robotparser,主要是用來識別網站的 robots.txt 檔案,然后判斷哪些網站可以爬,哪些網站不可以爬的,其實用的比較少,
在這里重點對前三個模塊進行下講解,

一、發送請求

使用 Urllib 的 request 模塊我們可以方便地實作 Request 的發送并得到 Response

1、urlopen()

urllib.request 模塊提供了最基本的構造 HTTP 請求的方法,利用它可以模擬瀏覽器的一個請求發起程序,同時它還帶有處理authenticaton(授權驗證),redirections(重定向),cookies(瀏覽器Cookies)以及其它內容,

我們來感受一下它的強大之處,以 Python 官網為例,我們來把這個網頁抓下來:

import urllib.request
?response = urllib.request.urlopen('https://www.python.org')
print(response.read().decode('utf-8'))

運行結果如下:

image

接下來我們看下它回傳的到底是什么,利用 type() 方法輸出 Response 的型別,

import urllib.request?
response = urllib.request.urlopen('https://www.python.org')
print(type(response))

輸出結果如下:

<class 'http.client.HTTPResponse'>

通過輸出結果可以發現它是一個 HTTPResposne 型別的物件,它主要包含的方法有 read()、readinto()、getheader(name)、getheaders()、fileno() 等方法和 msg、version、status、reason、debuglevel、closed 等屬性,

得到這個物件之后,我們把它賦值為 response 變數,然后就可以呼叫這些方法和屬性,得到回傳結果的一系列資訊了,

例如呼叫 read() 方法可以得到回傳的網頁內容,呼叫 status 屬性就可以得到回傳結果的狀態碼,如 200 代表請求成功,404 代表網頁未找到等,

下面再來一個實體感受一下:

import urllib.request
?
response = urllib.request.urlopen('https://www.python.org')
print(response.status)
print(response.getheaders())
print(response.getheader('Server'))

運行結果如下:

200
[('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'SAMEORIGIN'), ('X-Clacks-Overhead', 'GNU Terry Pratchett'), ('Content-Length', '47397'), ('Accept-Ranges', 'bytes'), ('Date', 'Mon, 01 Aug 2016 09:57:31 GMT'), ('Via', '1.1 varnish'), ('Age', '2473'), ('Connection', 'close'), ('X-Served-By', 'cache-lcy1125-LCY'), ('X-Cache', 'HIT'), ('X-Cache-Hits', '23'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]
nginx

可見,三個輸出分別輸出了回應的狀態碼,回應的頭資訊,以及通過呼叫 getheader() 方法并傳遞一個引數 Server 獲取了 headers 中的 Server 值,結果是 nginx,意思就是服務器是 nginx 搭建的

利用以上最基本的 urlopen() 方法,我們可以完成最基本的簡單網頁的 GET 請求抓取,

如果我們想給鏈接傳遞一些引數該怎么實作呢?我們首先看一下 urlopen() 函式的API:

urllib.request.urlopen(url, data=https://www.cnblogs.com/bigzql/p/None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

可以發現除了第一個引數可以傳遞 URL 之外,我們還可以傳遞其它的內容,比如 data(附加資料)、timeout(超時時間)等等,

下面我們詳細說明下這幾個引數的用法:

data引數

data 引數是可選的,如果要添加 data,它要是位元組流編碼格式的內容,即 bytes 型別,通過 bytes() 方法可以進行轉化,另外如果傳遞了這個 data 引數,它的請求方式就不再是 GET 方式請求,而是 POST,

下面用一個實體來感受一下:

import urllib.parse
import urllib.request
?
data = https://www.cnblogs.com/bigzql/p/bytes(urllib.parse.urlencode({'word': 'hello'}), encoding='utf8')
response = urllib.request.urlopen('http://httpbin.org/post', data=https://www.cnblogs.com/bigzql/p/data)
print(response.read())

在這里我們傳遞了一個引數 word,值是 hello,它需要被轉碼成bytes(位元組流)型別,其中轉位元組流采用了 bytes() 方法

第一個引數需要是 str(字串)型別,需要用 urllib.parse 模塊里的 urlencode() 方法來將引數字典轉化為字串,

第二個引數指定編碼格式,在這里指定為 utf8,

timeout引數

timeout 引數可以設定超時時間,單位為秒,意思就是如果請求超出了設定的這個時間還沒有得到回應,就會拋出例外,如果不指定,就會使用全域默認時間,它支持 HTTP、HTTPS、FTP 請求,

因此我們可以通過設定這個超時時間來控制一個網頁如果長時間未回應就跳過它的抓取,利用 try except 陳述句就可以實作這樣的操作,代碼如下:

import socket
import urllib.request
import urllib.error
?
try:
    response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:
    if isinstance(e.reason, socket.timeout):
        print('TIME OUT')

其他引數

還有 context 引數,它必須是 ssl.SSLContext 型別,用來指定 SSL 設定,
cafile 和 capath 兩個引數是指定 CA 證書和它的路徑,這個在請求 HTTPS 鏈接時會有用,

cadefault 引數現在已經棄用了,默認為 False,
以上講解了 urlopen() 方法的用法,通過這個最基本的函式可以完成簡單的請求和網頁抓取,如需更加詳細了解,可以參見官方檔案:

https://docs.python.org/3/library/urllib.request.html,

2. Request

由上我們知道利用 urlopen() 方法可以實作最基本請求的發起,但這幾個簡單的引數并不足以構建一個完整的請求,如果請求中需要加入 Headers 等資訊,我們就可以利用更強大的 Request 類來構建一個請求,
首先我們用一個實體來感受一下 Request 的用法:

import urllib.request
request = urllib.request.Request('https://python.org')
response = urllib.request.urlopen(request)
print(response.read().decode('utf-8'))

可以發現,我們依然是用 urlopen() 方法來發送這個請求,只不過這次 urlopen() 方法的引數不再是一個 URL,而是一個 Request 型別的物件,通過構造這個這個資料結構,一方面我們可以將請求獨立成一個物件,另一方面可配置引數更加豐富和靈活,

下面我們看一下 Request 都可以通過怎樣的引數來構造,它的構造方法如下:

class urllib.request.Request(url, data=https://www.cnblogs.com/bigzql/p/None, headers={}, origin_req_host=None, unverifiable=False, method=None)

第一個 url 引數是請求 URL,這個是必傳引數,其他的都是可選引數,

第二個 data 引數如果要傳必須傳 bytes(位元組流)型別的,如果是一個字典,可以先用 urllib.parse 模塊里的 urlencode() 編碼,

第三個 headers 引數是一個字典,這個就是 Request Headers 了,你可以在構造 Request 時通過 headers 引數直接構造,

也可以通過呼叫 Request 實體的 add_header() 方法來添加, Request Headers 最常用的用法就是通過修改 User-Agent 來偽裝瀏覽器,默認的 User-Agent 是 Python-urllib,我們可以通過修改它來偽裝瀏覽器,

第四個 origin_req_host 引數指的是請求方的 host 名稱或者 IP 地址,

第五個 unverifiable 引數指的是這個請求是否是無法驗證的,默認是False,意思就是說用戶沒有足夠權限來選擇接收這個請求的結果,例如我們請求一個 HTML 檔案中的圖片,但是我們沒有自動抓取影像的權限,這時 unverifiable 的值就是 True,

第六個 method 引數是一個字串,它用來指示請求使用的方法,比如GET,POST,PUT等等,

寫個例子:

from urllib import request, parse
?
url = 'http://httpbin.org/post'
headers = {
    'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
    'Host': 'httpbin.org'
}
dict = {
    'name': 'Germey'
}
data = https://www.cnblogs.com/bigzql/p/bytes(parse.urlencode(dict), encoding='utf8')
req = request.Request(url=url, data=https://www.cnblogs.com/bigzql/p/data, headers=headers, method='POST')
response = request.urlopen(req)
print(response.read().decode('utf-8'))

在這里我們通過四個引數構造了一個 Request,url 即請求 URL,在headers 中指定了 User-Agent 和 Host,傳遞的引數 data 用了 urlencode() 和 bytes() 方法來轉成位元組流,另外指定了請求方式為 POST,

通過觀察結果可以發現,我們成功設定了 data,headers 以及 method,
另外 headers 也可以用 add_header() 方法來添加,


req = request.Request(url=url, data=https://www.cnblogs.com/bigzql/p/data, method='POST')
req.add_header('User-Agent', 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')

如此一來,我們就可以更加方便地構造一個 Request,實作請求的發送啦,

二、 處理例外

我們了解了 Request 的發送程序,但是在網路情況不好的情況下,出現了例外怎么辦呢?這時如果我們不處理這些例外,程式很可能報錯而終止運行,所以例外處理還是十分有必要的,

Urllib 的 error 模塊定義了由 request 模塊產生的例外,如果出現了問題,request 模塊便會拋出 error 模塊中定義的例外,

主要有這兩個處理例外類,URLError,HTTPError

下面寫個例子:

from urllib import request, error
try:
    response = request.urlopen('http://cuiqingcai.com/index.htm')
except error.URLError as e:
    print(e.reason)

我們打開一個不存在的頁面,照理來說應該會報錯,但是這時我們捕獲了 URLError 這個例外,運行結果如下:

Not Found
from urllib import request,error
try:
    response = request.urlopen('http://cuiqingcai.com/index.htm')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, seq='\n')

運行結果:

Not Found
404
Server: nginx/1.4.6 (Ubuntu)
Date: Wed, 03 Aug 2016 08:54:22 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/5.5.9-1ubuntu4.14
Vary: Cookie
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache
Link: <http://cuiqingcai.com/wp-json/>; rel="https://api.w.org/"

HTTPError,它有三個屬性,

  • code,回傳 HTTP Status Code,即狀態碼,比如 404 網頁不存在,500 服務器內部錯誤等等,

  • reason,同父類一樣,回傳錯誤的原因,

  • headers,回傳 Request Headers,
    因為 URLError 是 HTTPError 的父類,所以我們可以先選擇捕獲子類的錯誤,再去捕獲父類的錯誤,所以上述代碼更好的寫法如下:

from urllib import request, error
?
try:
    response = request.urlopen('http://cuiqingcai.com/index.htm')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
    print(e.reason)
else:
    print('Request Successfully')

這樣我們就可以做到先捕獲 HTTPError,獲取它的錯誤狀態碼、原因、Headers 等詳細資訊,如果非 HTTPError,再捕獲 URLError 例外,輸出錯誤原因,最后用 else 來處理正常的邏輯,這是一個較好的例外處理寫法,

三、 實體抓取豆瓣電影排行榜

import urllib.parse
import urllib.request
url='https://movie.douban.com/'
herders={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36',
    'Referer':'https://movie.douban.com/',
    'Connection':'keep-alive'}
?
req=urllib.request.Request(url,headers=herders)
response=urllib.request.urlopen(req)
html=response.read().decode('utf8')
print(html)

結果


<!DOCTYPE html>
<html lang="zh-CN" >
<head>
     ...
    <title>豆瓣電影</title>  
?
    <meta name="keywords" content="電影、經典電影、熱映、電視劇、美劇、影評、電影院、電影票、排行、推薦"/>
    <meta name="description" content="豆瓣電影提供最新的電影介紹及評論包括上映影片的影訊查詢及購票服務,你可以記錄想看、在看和看過的電影電視劇,順便打分、寫影評,根據你的口味,豆瓣電影會推薦好電影給你," />
    ....
    以下省略

四、分析Robots協議

利用urllib的robotparser模塊,我們可以實作網站Robots協議的分析

1Robots協議

Robots協議也稱為爬蟲協議、機器人協議,它的全名叫做網路爬蟲排除標準(Robots Exclusion Protocol),用來告訴爬蟲和搜索引擎哪些網頁可以抓取,哪些不可以抓取,它通常是一個robots.txt的文本檔案,一般放在網站的根目錄下,

當搜索爬蟲訪問一個站點時,它首先會檢查這個站點根目錄下是否存在robots.txt檔案,如果存在,搜索爬蟲會根據其中定義的爬去范圍來爬取,如果沒有找到,搜索爬蟲會訪問所有可直接訪問的頁面

我們來看下robots.txt的樣例:

User-agent: *
Disallow: /
Allow: /public/

它實作了對所有搜索爬蟲只允許爬取public目錄的功能,將上述內容保存為robots.txt檔案放在網站根目錄下,和網站的入口檔案(index.html)放在一起

User-agent描述了搜索爬蟲的名稱,將其設定為*則代表協議對任何爬蟲有效,如設定為Baiduspider則代表規則對百度爬蟲有效,如果有多條則對多個爬蟲受到限制,但至少需要指定一條

一些常見的搜索爬蟲名稱:

BaiduSpider  百度爬蟲   www.baidu.com
Googlebot  Google爬蟲   www.google.com
360Spider  360爬蟲   www.so.com
YodaoBot  有道爬蟲   www.youdao.com
ia_archiver  Alexa爬蟲   www.alexa.cn
Scooter  altavista爬蟲     www.altavista.com

Disallow指定了不允許抓取的目錄,如上例中設定的/則代表不允許抓取所有的頁面

Allow一般和Disallow一起使用,用來排除單獨的某些限制,如上例中設定為/public/則表示所有頁面不允許抓取,但可以抓取public目錄

設定示例:

#禁止所有爬蟲
User-agent: *
Disallow: /
?
#允許所有爬蟲訪問任何目錄,另外把檔案留空也可以
User-agent: *
Disallow:
?
#禁止所有爬蟲訪問某那些目錄
User-agent: *
Disallow: /home/
Disallow: /tmp/
?
#只允許某一個爬蟲訪問
User-agent: BaiduSpider
Disallow:
User-agent: *
Disallow: /

2 robotparser

rebotparser模塊用來決議robots.txt,該模塊提供了一個類RobotFileParser,它可以根據某網站的robots.txt檔案來判斷一個抓取爬蟲時都有權限來抓取這個網頁

urllib.robotparser.RobotFileParser(url='')

robotparser類常用的方法:

set_url():用來設定robots.txt檔案的連接,如果在創建RobotFileParser物件是傳入了連接,就不需要在使用這個方法設定了

read():讀取reobts.txt檔案并進行分析,它不會回傳任何內容,但執行那個了讀取和分析操作

parse():用來決議robots.txt檔案,傳入的引數是robots.txt某些行的內容,并安裝語法規則來分析內容

can_fetch():該方法傳入兩個引數,第一個是User-agent,第二個是要抓取的URL,回傳的內容是該搜索引擎是否可以抓取這個url,結果為True或False

mtime():回傳上次抓取和分析robots.txt的時間

modified():將當前時間設定為上次抓取和分析robots.txt的時間

#!/usr/bin/env python
#coding:utf8
from urllib.robotparser import RobotFileParser
rp = RobotFileParser()  #創建物件
rp.set_url('https://www.cnblogs.com/robots.txt') #設定robots.txt連接,也可以在創建物件時指定
rp.read()  #讀取和決議檔案
print(rp.can_fetch('*','https://i.cnblogs.com/EditPosts.aspx?postid=9170312&update=1'))

希望各位同學以后在寫爬蟲時候可以遵循 Robot 協議,為了自己的安全著想,

image

IT入門 感謝關注 |  練習地址:www.520mg.com/it

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/167652.html

標籤:Python

上一篇:提升Python性能的7個習慣

下一篇:桶排序的簡單實作

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more