日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

2021-09-01 学习笔记:Python爬虫、数据可视化

發布時間:2024/1/18 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021-09-01 学习笔记:Python爬虫、数据可视化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2021-09-01 學習筆記:Python爬蟲、數據可視化

結于2021-09-07;
內容來自 成都工業大學 數字媒體專業實訓;

主要內容:

  • PyCharm開發Python腳本的基礎配置;
  • Python爬蟲基礎:正則匹配(re)、網頁獲取(urllib)、網頁解析(bs4/BeautifulSoup)
  • 數據存儲:數據庫操作(sqlite3/pymysql)、簡單excel編輯(xlwt);
  • 數據可視化:Flask:Web框架、 Echarts、 WordCloud

內容很豐富,老師講的很好;
筆記內容僅對個人知識進行補充,詳細課程可以自行學習;

開發環境

Python無法進行代碼加密;

Python安裝及環境變量設置:

  • 環境變量:Python目錄 和 該目錄下的Scripts工具目錄;

PyCharm IDE;

  • 這里使用anaconda提供的conda環境,管理Pyhton版本,沒有單獨安裝和配置Pyhton,這里新初始化的環境是Python3.9;
  • 初始化一個python工程項目;
  • IDE右上角,或cmd+,打開設置,Editor->Font,可以設置字體;
  • Editor->File and Code Templates,可以設置模塊通用的模板;
  • 檢查當前項目的Python解釋器路徑,如果與新建項目時不符,則需要進行解釋器路徑的配置;

  • 這里第一張圖,也是當前環境安裝Python擴展庫的地方(還可以指定安裝源),目前顯示了已將安裝的擴展庫;
  • 模塊通用的模板示例如下:
#Author:Flower # -*- coding = utf-8 -*- # @Time:${DATE} ${TIME} # @Author:${USER} # @Site:${SITE} # @File:${NAME}.py # @Software:${PRODUCT_NAME}

  • 新建一個腳本,打印一條語句,右鍵選中腳本文件,選擇Run即可運行程序;
  • 雙擊文件名進行文件編輯
  • 文件名修改方式如下:


Pyhton基礎

  • 查看關鍵字:
import keyword keyword.kwlist # ['False', 'None', 'True', '__peg_parser__', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
  • 邏輯與或非:and/or/not
  • 判斷在不在序列:in/not in
  • 判斷是不是類實例:is/is not
import random random.randint(0, 2) # 0,1,2 隨機一個
  • break continue pass
  • Python3默認是UTF-8編碼,所有字符串都是unicode字符串;

其他基礎內容參考Learning Python的學習筆記,這里略過;


Python爬蟲基礎

需求:

  • 爬取豆瓣電影Top250,信息;

爬蟲基礎知識:

  • 根據用戶需求定向,自動抓取互聯網信息的腳本;

百度指數可以對比關鍵字的檢索量,如電影天堂,愛奇藝;電影天堂通過網絡資源引流,廣告變現;天眼查通過整合信息,賣會員變現;

請求網頁:

  • cookies:用戶信息
  • user-agent:瀏覽器信息

涉及到的庫:

import sys import re # 正則匹配 import urllib.request, urllib.error # 獲取網頁 import sqlite3 # sqlite數據庫操作 import bs4 # 解析網頁 from bs4 import BeautifulSoup # 解析網頁 import xlwt # excel操作

Python3 的urllib 整合了urllib2的功能,現在只需要用urllib即可;

測試的網址:

  • httpbin.org這是github的一個測試網絡請求和響應的網址;

urllib

import urllib.request import urllib.parse import urllib.errorclass HQUrlLibBlocking:def __init__(self):self.headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'}def getRequestParseHtmlFromUrlSimple(self, url):"""進行get請求,直接打開網頁,獲取網頁信息"""try:response = urllib.request.urlopen(url, timeout=15)print(response.status)html_r = response.read().decode('utf-8')return html_rexcept urllib.error.URLError as e:print(e)def getRequestParseHtmlFromUrl(self, url):"""進行get請求,直接打開網頁,獲取網頁信息"""try:request = urllib.request.Request(url, headers=self.headers, method='GET')response = urllib.request.urlopen(request, timeout=15)print(response.status)html_r = response.read().decode('utf-8')return html_rexcept urllib.error.URLError as e:print(e)def postRequestParseHtmlFromUrlSimple(self, url, params):"""進行post請求,未攜帶header瀏覽器信息,獲取網頁信息"""try:data = bytes(urllib.parse.urlencode(params), encoding='utf-8')response = urllib.request.urlopen(url, data=data, timeout=15)print(response.status)html_r = response.read().decode('utf-8')return html_rexcept urllib.error.URLError as e:print(e)def postRequestParseHtmlFromUrl(self, url, params):"""進行post請求,獲取網頁信息"""try:data = bytes(urllib.parse.urlencode(params), encoding='utf-8')request = urllib.request.Request(url, data=data, headers=self.headers, method='POST')response = urllib.request.urlopen(request, timeout=15)print(response.status)html_r = response.read().decode('utf-8')return html_rexcept urllib.error.URLError as e:print(e)if __name__ == '__main__':content_get = HQUrlLibBlocking().getRequestParseHtmlFromUrl('http://httpbin.org/get')print(content_get)postParams = {'hello':'world'}content_post = HQUrlLibBlocking().postRequestParseHtmlFromUrl('http://httpbin.org/post',postParams)print(content_post)print('over')

BeautifulSoup4

with open('./testBS4.html','rb') as file:html = file.read()# 將復雜的HTML文檔轉換成復雜的樹形結構,每個節點都是Python對象bs = BeautifulSoup(html, 'html.parser')print(bs.title)print(bs.li)print(bs.title.string)print(bs.li.attrs)t_list = bs.find_all('li')print(t_list)
  • 將復雜的HTML文檔轉換成復雜的樹形結構,每個節點都是Python對象,所有對象可以歸納為4種;
  • Tag:html文檔標簽對象,默認只拿到第一個;
  • NavigableString:Tag包裹的內容.string,Tag的屬性.attrs;
  • BeautifulSoup:整個Document文檔對象;
  • Comment:注釋,會不包含注釋符號,只顯示其中文字,是一種特殊的NavigableString;
bs.head.contentsbs.body.childrent_list = bs.find_all('li') # 字符串匹配 t_list = bs.find_all(re.compile('li')) # 字符串包含def class_is_exists(tag):return tag.has_attr('class') t_list = bs.find_all(class_is_exists) # 符合條件 t_list = bs.find_all(id='head') t_list = bs.find_all(class_=True) t_list = bs.find_all('div', class_=True) t_list = bs.find_all(text='hao123') t_list = bs.find_all(text=['hao123','地圖','貼吧'])t_list = bs.find_all('a', limit=2)# 選擇器 t_list = bs.select('title') # 通過tag查找 t_list = bs.select('.class') # 通過class查找 t_list = bs.select('#id') # 通過id查找 t_list = bs.select("a[name='haha']") # 通過屬性查找 t_list = bs.select('head > title') # 通過子標簽查找 t_list = bs.select('.class1 ~ .class2') # 通過兄弟標簽查找t_list[0].get_text()

正則表達式

判斷字符串是否符合一定的模式

re模塊:

  • re.search():在一個字符串中搜索匹配正則的第一個位置,返回match對象
  • re.match():從一個字符串的開始位置匹配正則,返回match對象
  • re.findall():搜索字符串,以列表類型返回全部能匹配到的子串
  • re.split():將一個字符串按照正則匹配結果進行分割,返回列表
  • re.finditer():搜索字符串,返回一個匹配結果的迭代類型,迭代元素是match對象
  • re.sub():在一個字符串中替換所有匹配正則的子串,返回替換后的字符串

re模式:

  • 標志修飾符控制匹配模式;
  • 多個表示按位|來設置,如re.I | re.M;
  • re.I:使匹配對大小寫明暗
  • re.L:做本地化識別(locale-aware)匹配
  • re.M:多行匹配,影響^ $
  • re.S:使.匹配包括換行在內的所有字符
  • re.U:更具Unicode字符集解析字符,影響\w \W \b \B
  • re.X:該標志通過給予更靈活的格式,便于理解正則
import re# 使用模式對象 pattern_o = re.compile(r"AA") # r字符串中不會轉義字符 match_o = pattern_o.search("ahwuefauwefhaw")# 不使用模式對象 match_o = re.search(r"AA", "ahwuefauwefhaw")# 字符替換 re.sub(r"a","A", ahwuefauwefhaw) # 匹配到a 用A替換

正則表達式知識,可參考《正則校驗-我需要的正則表達式知識》

示例程序

findLink = re.compile(r'<a href="(.*?)">') findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # ?非貪婪 findTitle = re.compile(r'<span class="title">(.*)</span>') # 貪婪 ...bs = BeautifulSoup(html, "html.parser") # 使用bs縮小范圍到item for item in bs.find_all('div', class_ = 'item'):item = str(item)# 在item的字符串中 通過正則進行匹配link = re.findall(findLink, item)[0]titles = re.findall(findTitle, item)# 其他判斷 或字符串替換處理if len(titles) == 2:c_title = titles[0]o_title = titles[1]

數據保存

  • excel操作
  • 數據庫操作

excel表保存

  • 利用Python庫xlwt將數據寫入excel表格;
import xlwtworkbook = xlwt.Workbook(encoding='utf-8') # 創建workbook worksheet = workbook.add_sheet('sheet1') # 創建工作表 worksheet.write(0,1, 'hello') # 第0行 第1列 單元格寫入 內容 worksheet.save('./test.xls') # 保存到excel

這個和Pandas對excel的操作比,還是有點low;

sqlite數據庫保存

  • 數據類型(支持這五個數據類型相關的親和類型):
    • NULL
    • INTEGER:帶符號整數,根據值的大小存儲在1 2 3 4 6 8字節中
    • REAL:浮點數,存儲為8字節浮點數字
    • TEXT:文本字符串,使用數據庫編碼存儲
    • BLOB:blob數據,完全根據它的輸入存儲
import sqlite3# 打開或創建數據庫 connect = sqlite3.connect('douban_top.db') # 獲取游標 cursor = connect.cursor()# 建表SQL sql = """create table company (id int primary key not null autoincrement,name text not null,age int not null,address char(50),salary real);""" # 執行 cursor.execute(sql) # 提交 connect.commit()# 查詢SQL sql_select = """select id,name,age,address,salary from company; """ cursor_res = cursor.execute(sql_select) for row in cursor_res:print('id', row[0])print('name', row[1])print('age', row[2])print('address', row[3])print('salary', row[4])# 關閉 cursor.close() cursor_res.close() connect.close()

其他數據庫基本操作參考《SQL-深入淺出》

mysql數據庫操作

from pymysql import *connect = connect(host='127.0.0.1', port=3306, user='usre',password='password',database='hq_test_local',charset='utf-8')cursor = connect.cursor()cursor.execute('SELECT * FROM %s'%(xm_provinces)) results = cursor.fetchall()# 其他操作基本一致 # 這個函數用來判斷表是否存在 def table_exists(self,table_name): sql = "show tables;"self.cur.execute(sql)tables = [self.cur.fetchall()]table_list = re.findall('(\'.*?\')',str(tables))table_list = [re.sub("'",'',each) for each in table_list]if table_name in table_list:return 1 #存在返回1else:return 0 #不存在返回0

如果是使用Navicat Premium進行表結構創建,也可以查看具體表結構創建的SQL:

  • 選中表,右鍵存儲SQL文件,僅結構;
  • 保存的sql文件中就有對應的創建表的SQL語句;
DROP TABLE IF EXISTS "user"; CREATE TABLE "user" ("id" integer PRIMARY KEY AUTOINCREMENT,"name" text(40,1),"age" integer(4) );

數據可視化

  • Flask:Web框架
  • Echarts
  • WordCloud

Flask

Flask:

  • 是用Python基于Werkzeug工具箱編寫的輕量級web開發框架,面向需求簡單的小應用;
  • Flask本身相當于一個內核,其他功能基本都需要第三方擴展,如可以用Flask-extension加入ORM、窗體驗證工具、文件上傳、身份驗證等;
  • Flask沒有默認使用的數據庫,可以使用MySQL,也可以使用NoSQL;
  • WSGI 采用 Werkzeug(路由模塊)
  • 模板引擎適應Jinja2;

關于另一個fastAPI,也可以嘗試使用;

快速網站框架:

  • 所有Flask程序都必須創建一個程序實例;
  • 客戶端要獲取資源時,一般會通過瀏覽器發起HTTP請求;
  • Web服務器使用名為WEB服務器網關接口的WSGI(Web Server Gateway Interface)協議,把來自客戶端的請求交給Flask程序實例;
  • 一個HTTP請求,對應Server端一個處理邏輯;
  • Flask使用Werkzeug來做路由分發(URL請求和視圖函數之間的對應關系);根據每個URL請求,找打具體的視圖函數;
  • 在Flask程序中,路由一般是通過程序實例的裝飾器實現;通過調用視圖函數,獲取到數據后,把數據傳入HTML模板文件中,模板引擎負責渲染HTTP響應數據,然后右Flask返回響應數據給瀏覽器,最后瀏覽器顯示;

Django是一個大而全的框架,更適合工程化開發;

Flask擴展包:

  • Flask-SQLLalchemy 操作數據庫
  • Flask-migrate 管理遷移數據庫
  • Flask-Mail 郵件
  • Flask-WTF 表單
  • Flask-script 插入腳本
  • Flask-Login 認證用戶狀態
  • Flask-RESTful 開發REST API工具
  • Flask-Bootstrap 集成前端框架
  • Flask-Moment 本地化日期和時間

pip install flask

from flask import Flaskapp = Flask(__name__)# 裝飾器的作用是將路由映射到視圖函數index @app.route('/') def index():return 'Hello world!'if __name__ == "__main__":# 啟動web服務器app.run()

項目目錄:

app.py # hello world static # 網頁靜態資源 templates # html模板

flask的 Debug Mode開啟

修改代碼后,刷新界面就可以看到相應的變化;

# 1.修改當前執行項目的configuration,開啟Flask的debug模式# 2.代碼設置 app.run(debug=True)

注:第一步如果創建的是Flak項目,才會有,如果是調用Flask庫進行的調試,直接使用代碼設置就可以了;

flask路由參數解析

# 字符串參數 @app.route("/user/<name>") def welcome(name):return name# 數字參數: int float @app.route("/user/<int:id>") def welcome(id):return str(id)

注:路由路徑不可以重復;

html模板-Jinja2

pip install jinja2,安裝Flask時應該已經帶了;

from flask import Flask, render_templateapp = Flask(__name__)@app.route("/") def welcome():return render_template('index.html')if __name__ == '__main__':app.run(debug=True)

相應的index.html是定義在templates目錄下的html文件;

html的動態渲染

import datetime from flask import Flask, render_templateapp = Flask(__name__)# 三種變量 @app.route("/") def welcome():# 普通變量time = datetime.date.today()# 列表names = ['a', 'b', 'c']# 字典task = {"work":"WK", "time":"30min"}return render_template('index.html', var=time, list=names, task=task)if __name__ == '__main__':app.run(debug=True) <!--解析結構--><div>Today is {{ var }}</div><ul> <!--控制結構-->{% for name in list %}<li>{{ name }}</li>{% endfor %}</ul> <!--使用表格--><table border="1"> <!--items方法 對應的是一個元組列表 -->{% for key, value in task.items() %}<tr><td>{{key}}</td><td>{{value}}</td></tr>{% endfor %}</table>

表單提交

from flask import Flask, render_template, request app = Flask(__name__)# 表單提交頁面 @app.route("/test/register") def register():# templates目錄的文件結構return render_template('test/register.html')# 表單提交請求,必須顯式指定接收方式 @app.route("/test/regist", methods=['POST', 'GET']) def regist():# 通過request獲取請求信息request.method # 請求方式request.form # form表單字典# templates目錄的文件結構return render_template('test/regist.html') # 提示:注冊成功或失敗if __name__ == '__main__':app.run(debug=True)

動態獲取請求url根路徑:

<!-- <form method="post" action="http://localhost:5000/test/regist">--><!--動態獲取網址根路徑--><form method="post" action="{{ url_for('test/regist') }}"><label>姓名:<input type="text" name="name"></label><label>年齡:<input type="text" name="age"></label><input type="submit" value="Submit"></form>

網頁模板

下載靜態網頁模板進行使用:

  • 模板之家;
  • BOOTSTAPMADE;
  • colorlib;

步驟:

  • index.html 放入 templates目錄
  • assets 文件夾 放入 static目錄,便于CDN服務器分發;
  • 在index.html中 修改引入assets資源的路徑;
  • 在index.html中的,保留并修改實際使用部分,其余部分刪除即可;

其他:

  • 圖標資源,可以在iconfont上進行下載,替換使用;
  • 超鏈接的路由跳轉:<a href='/move'></a>
  • 路由跳轉的新頁面,為保持風格,可以在原靜態網頁模板的基礎上再行調整;

列表展示

@app.route('/movie') def movie():datalist = []con = sqlite3.connect("movie.db")cur = con.cursor()sql = "select * from movie250"data = cur.execute(sql)for item in data:datalist.append(item)cur.close()con.close()return render_template("movie.html", movies = datalist) <table class="table table-striped"><tr><td>排名</td><td>名稱</td></tr>{% for movie in movies %}<tr><td>{{movie[0]}}</td><td><a href="{{movie[2]}}" target="_blank">{{movie[1]}}</a></td></tr>{% endfor %} </table>

拓展:如何支持分頁?

Echarts

圖表展示

  • 在assets/js目錄下,導入echarts.min.js,也可以通過npm來安裝;
  • 編寫圖表展示的html頁面,并引入js,<script src="static/assets/js/echarts.min.js"></script>;

詳細示例和教程參考官網 文檔-配置項 即可;

圖表代碼可以copy,也可以download完整的圖表html;

@app.route('/score') def score():score = []num = []con = sqlite3.connect("movie.db")cur = con.cursor()sql = "select score, count(score) from movie250 group by score"data = cur.execute(sql)for item in data:score.append(item[0])num.append(item[1])cur.close()con.close()return render_template("scrore.html", score = score, num = num) xAxisdata: {{score|tojson}} seriexdata: {{num}}

這里如果 score 是一個字符串數組,為避免從數據庫讀出的字符串包含特殊字符,可以使用tojson進行轉換;

WordCloud應用

詞云:

  • 詞頻高的展示文字大一些;
  • 文檔中提供了許多示例,可以參考;
  • 如果要支持中文,需要安裝pip install jieba進行中文分詞;

這是文檔中的一個常見示例的實現代碼:

import osfrom os import path from wordcloud import WordCloud# get data directory (using getcwd() is needed to support running example in generated IPython notebook) d = path.dirname(__file__) if "__file__" in locals() else os.getcwd()# Read the whole text. text = open(path.join(d, 'constitution.txt')).read()# Generate a word cloud image wordcloud = WordCloud().generate(text)# Display the generated image: # the matplotlib way: import matplotlib.pyplot as plt plt.imshow(wordcloud, interpolation='bilinear') plt.axis("off")# lower max_font_size wordcloud = WordCloud(max_font_size=40).generate(text) plt.figure() plt.imshow(wordcloud, interpolation="bilinear") plt.axis("off") plt.show()# The pil way (if you don't have matplotlib) # image = wordcloud.to_image() # image.show()

我們的網站嵌入詞云:

# pip install jieba import jieba # 分詞 # pip install matplotlib from matplotlib import pyplot as plt # 繪圖 保存 # pip install wordcloud from wordcloud import WordCloud # 詞云from PIL import Image # 圖片處理的庫 import numpy as np # 矩陣運算 import sqlite3 # 數據庫# 獲取文本數據 con = sqlite3.connect('movie.db') cur = con.cursor() sql = 'select instruction from movie250' data = cur.execute(sql) text = '' for item in data:text = text + item[0] cur.close() con.close() # 分詞處理 cut = jieba.cut(text) cut_str = ' '.join(cut)# 遮罩生成詞云 img = Image.open(r"./一張白底的形狀圖.png") img_array = np.array(img)wc = WordCloud(background_color='white',mask=img_array,font_path="msyh.ttc" ) wc.generate_from_text(cut_str)# 繪制圖片 fig = plt.figure(1) plt.imshow(wc) plt.axis('off') # 不顯示坐標軸 # plt.show() plt.save('./static/assets/img/wordcloud.png', dpi=500)

Wordcloud安裝不成功的處理:

  • 從非官網Python擴展包下載wordcloud模塊的whl文件,名如wordcloud-1.6.0-cp37m-win32.whl,注意這里cp后邊是python版本;
  • 使用命令pip install wordcloud-1.6.0-cp37m-win32.whl進行安裝;
  • 另外,如果用的是conda的環境,注意記得切換;

WordCloud 配置

WordCloud:

  • font_path string 字體路徑
  • width int 輸出畫布寬,默認400像素
  • height int 輸出畫布高,默認200
  • prefer_horizontal float 默認0.9 詞語水平方向排版的概率,相當于垂直方向排版概率0.1
  • mask nd-array 默認None 繪制詞云使用的二維遮罩,全白的部分不會被繪制;
  • scale float 默認1 表示畫布縮放的比例
  • min_font_size int 默認4 顯示上最小的字體大小
  • max_font_size
  • font_step int 默認1 字體步長,大于1時,運算會快些,但誤差也大;
  • max_words number 默認200, 要顯示詞的最大個數
  • stopwords set of strings 空時使用內置默認的集合,用于設置需要屏蔽的詞;
  • background_color 生成圖片的背景顏色
  • mode 默認RGB;可以設置為RGBA,若此時background_color非空,則背景透明
  • relative_scaling float 默認0.5 表示詞頻與字體大小的關聯性
  • color_func 生成新顏色的函數,為空時,使用默認的方法;
  • regexp 正則表達式,用于分割輸入的文本
  • collocations bool 默認True,表示是否包括兩個詞的搭配
  • colormap 默認viridis,給每個單詞隨機分配顏色,若指定color_func,這被忽略;
  • fit_words(frequencies) 根據詞頻生成詞云
  • generate(text) 根據文本生成詞云
  • generate_from_frequencies(frequencies) 根據詞頻生成詞云
  • generate_from_text(text) 根據文本生成詞云
  • to_array() 轉化為 numpy array
  • to_file(filename) 輸出到文件

Over!

總結

以上是生活随笔為你收集整理的2021-09-01 学习笔记:Python爬虫、数据可视化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。