Python爬蟲之爬取各大幣交易網站公告——靜態網站.md
Python爬蟲之爬取各大幣交易網站公告——靜態網站
瞭解爬蟲之後,我們也漸漸掌握了根據網站的種類選擇不同庫來對其進行處理,提取我們想要的東西。
靜態網站,我們往往利用requests庫提取網站html資訊,再通過正則表示式或BeautifulSoup庫提取我們想要的資訊。
注:本人面向物件目前還在學習,文中一切全為面向過程。
Python版本:Python3.X
執行平臺:Windows
IDE:PyCharm
瀏覽器:Chrome
目標:獲取公告標題時間連結,並以時間倒序,只輸出本地時間前一天的公告內容。
靜態網站
方法:利用正則表示式,requests庫。由於這些網站操作幾乎一樣,此處便只以中幣為例。
第一步,根據URL獲取網頁的HTML資訊
利用requests庫進行網頁爬取。
import requests
if __name__=='__main__':
target = 'https://www.zb.cn/i/blog?type=proclamation'
req = requests.get(url=target)
html = req.content
html_doc = str(html, 'utf-8')
print(html_doc)
執行結果如下:
我們獲得了HTML資訊,接下來我們將要從中提取我們想要的公告標題時間以及其連結。
這裡我們使用正則表示式。
第二步,利用正則表示式提取所需內容
首先同樣對網站進行檢查,得到如下介面:
我們可以很清楚的看到我們想要的公告時間標題和連結,接下來就是從這些標籤中提取資訊了。
根據正則,我們知道我們只要匹配**<a href=“和target=”_blank">**就可以了。然後我們嘗試一下:
正則表示式和程式碼如下:
href = re.findall(r'<a.href="(.*?)".target="_blank">', html_doc)
import requests import re if __name__=='__main__': target = 'https://www.zb.cn/i/blog?type=proclamation' req = requests.get(url=target) html = req.content html_doc = str(html, 'utf-8') href = re.findall(r'<a.href="(.*?)".target="_blank">', html_doc) num=len(href) n=0 while(n<num): print(href[n]) n=n+1
執行得到:
我們再看看檢查網站:
對比發現,我們確實得到了每一個公告的連結,但是每一個連結確實重複出現的,而且執行結果的第一個連結不是我們需要的,那我們接下來就需要更精確的匹配了。
再次檢查網站:
我們看到我們想要的連結和標題全在
標籤下,那我們是不是可以先提取
標籤的內容再提取其中的連結和標題呢?
嘗試一下:
content = re.findall(r'<h3>(.*?)</h3>', html_doc, re.S)
執行得到:
我們發現我們得到了連結和標題,現在需要做的就是進行再次提取。
我們知道findall()提取的是列表,我們現在需要從中提取元素,其中每一個元素包括一個連結和標題。這裡我們需要用到迴圈。
import requests
import re
if __name__=='__main__':
target = 'https://www.zb.cn/i/blog?type=proclamation'
req = requests.get(url=target)
html = req.content
html_doc = str(html, 'utf-8')
content = re.findall(r'<h3>(.*?)</h3>', html_doc,re.S)
a = len(content)
n = 0
while (n < a):
href = re.findall(r'<a href="(.*?)".target="_blank">',content[n], re.S)[0]
href = 'https://www.zb.cn%s' % href
title = re.findall(r'.target="_blank">(.*?)</a>',content[n], re.S)[0]
print(title,href)
n=n+1
執行結果如下:
我們發現方法確實,不過標題和連結正好錯開一行,接下來利用strip()清除空格換行
將 print(title,href)改成print(title.strip(),href),執行得到:
成功完成。
接下來提取時間,一種是在公告網站再次利用正則提取,另一種便是進入每一條公告連結的網站中進行提取。
我用的是第二種。注:方法很多,歡迎與我交流~
我們已經得到了連結,自然可以再次利用requests庫得到每一個連結HTML資訊,並利用正則表示式從中獲取時間資訊。只需要在迴圈中加入以下程式碼:
target = href
req = requests.get(url=target)
html = req.content
html_doc = str(html, 'utf-8')
time = re.findall(r'釋出時間.<span>(.*?)</span> ', html_doc,re.S)[0]
執行得到:
第三步,提取前一天公告
我們已經將所需內容全部獲取,現在只需要提取前一天公告,利用如下程式碼得到前一天日期:
now_time = datetime.datetime.now() yes_time = now_time + datetime.timedelta(days=-1) yes_time_nyr = yes_time.strftime('%Y-%m-%d')
程式碼如下:
import requests
import re
import datetime
if __name__=='__main__':
now_time = datetime.datetime.now()
yes_time = now_time + datetime.timedelta(days=-1)
yes_time_nyr = yes_time.strftime('%Y-%m-%d')
target = 'https://www.zb.cn/i/blog?type=proclamation'
req = requests.get(url=target)
html = req.content
html_doc = str(html, 'utf-8')
content = re.findall(r'<h3>(.*?)</h3>', html_doc,re.S)
a = len(content)
n = 0
judge=[]
while (n < a):
href = re.findall(r'<a href="(.*?)".target="_blank">',content[n], re.S)[0]
href = 'https://www.zb.cn%s' % href
title = re.findall(r'.target="_blank">(.*?)</a>',content[n], re.S)[0]
target = href
req = requests.get(url=target)
html = req.content
html_doc = str(html, 'utf-8')
time =re.findall(r'釋出時間.<span>(.*?)</span> ', html_doc,re.S)[0]
all=time+title.strip()+href
if yes_time_nyr in all:
print(all)
judge+=all
n=n+1
if(len(judge))==0:
print('本日無公告')
特例(1)
當我們用以上方法爬取位元兒時,我們會發現結果是這樣的:
我們發現我們得到的公告是英文,而瀏覽該網站時,我們卻發現公告是中文
觀察網站我們發現它還有其他語言版本。
接下來我們對中文版本和英文版本進行比較
用F12熱鍵,找到Network點選XHR,重新整理得到:
接下來點選ann,進入後會發現如下資訊:
同樣我們進入英文版介面得到相同資訊。兩者對比,我們發現這兩個幾乎完全相同,只有Cookie不同。
Cookie:
market_title=usdt; __ca__chat=viaGJUV1FD2z; Hm_lvt_0a1ead8031fdf1a7228954da1b158d36=1537678616,1538365833; sc_is_visitor_unique=rx11802877.1538365914.CE52C987E49E4FD2316BEC49E4353B91.1.1.1.1.1.1.1.1.1; Hm_lpvt_0a1ead8031fdf1a7228954da1b158d36=1538368920; lang=en; lasturl=%2Farticlelist%2Fann; sc_is_visitor_unique=rx11802852.1538368929.CE52C987E49E4FD2316BEC49E4353B91.1.1.1.1.1.1.1.1.1-11802877.1538365914.1.1.1.1.1.1.1.1.1
Cookie:
market_title=usdt; __ca__chat=viaGJUV1FD2z; Hm_lvt_0a1ead8031fdf1a7228954da1b158d36=1537678616,1538365833; sc_is_visitor_unique=rx11802877.1538365914.CE52C987E49E4FD2316BEC49E4353B91.1.1.1.1.1.1.1.1.1; lang=cn; lasturl=%2Farticlelist%2Fann; sc_is_visitor_unique=rx11802877.1538370060.CE52C987E49E4FD2316BEC49E4353B91.2.2.1.1.1.1.1.1.1; Hm_lpvt_0a1ead8031fdf1a7228954da1b158d36=1538370061
所以我們猜測可能是因為Cookie的原因,我們嘗試一下:
import requests
import re
import datetime
if __name__=='__main__':
now_time = datetime.datetime.now()
yes_time = now_time + datetime.timedelta(days=-1)
yes_time_nyr = yes_time.strftime('%Y-%m-%d')
f = open(r'cookies.txt', 'r')
cookies = {}
for line in f.read().split(';'):
name, value = line.strip().split('=', 1)
cookies[name] = value
target = 'https://www.gateio.io/articlelist/ann'
req = requests.get(url=target,cookies=cookies)
html = req.text
content = re.findall(r'<a href="(.*?).title="(.*?)\d*".target="_blank"',html)
a = len(content)
n = 0
judge = []
while (n < a):
url = content[n][0]
url = 'https://www.gateio.io%s' % url
url = url.replace('"', '')
title = content[n][1]
n = n + 1
target = url
req = requests.get(url=target)
html = req.text
news = re.findall(r'<div class="new-dtl-info">(.*?)</div>', html, re.S)[
0]
time = re.findall(r'<span>(.*?)</span>', news)[0]
all = time + '\t' + title + '\t' + url
if yes_time_nyr in all:
print(all)
judge += all
if len(judge) == 0:
print('本日無公告')
其中cookies.txt文件中存入我們得到的中文版的cookie。
執行得到:
目標完成。
特例(2)
有的網站在爬取後我們會發現得到的時間資訊為格林時間,需要自己進行轉換,這裡給出轉換程式碼如下:
utc = time
UTC_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
utcTime = datetime.datetime.strptime(utc, UTC_FORMAT)
localtime = utcTime + datetime.timedelta(hours=8)
其中time為格林時間。