大數據

Python學習筆記

環境配置

版本查看

正常情況下 linux mac os 默認安裝python2環境,使用以下命令查看版本號

python -V

python3 -V

Python 3.0 於2008年12月3日正式發佈,但python2和python3互不兼容,Python 2.7 於 2020 年 4 月 停止維護!由於歷史遺留問題 目前仍有大量代碼沒有遷移到python3

安裝

Mac OS brew install python3

Linux apt install python3 apt-get install python3 .....

Windows 官網下載安裝包>安裝> 配置環境變量

使用

進入Python shell

交互式 Python python3

交互式編程常用於數據分析等領域 jupyter notebook

文件式 python 程序.py python3 程序.py

模塊安裝

正常情況下 安裝python後會自帶pip包管理器 如果沒有可以使用以下命令安裝

brew install python3-pip

pip install 模塊名 pip3 install 模塊名

requests 第三方網絡請求模塊

pip install requests

代碼規範

js
//寫法1
function    getList(id){
  if (id == 1){
            console.log('小明');    
  }else{
        console.log('張三');   
  }
},
  
//寫法2
function    getList(id){
  if (id == 1){console.log('小明');}else{console.log('張三');}
},
  
//寫法3
function    getList(id){if (id == 1){console.log('小明');}else{console.log('張三');}},
python
#通過縮進來區分代碼塊
#代碼結尾不能加分號
#代碼塊不能使用

def getList(id):
    if id == 1:
        print('小明')
    else:
        print('張三')
    

爬蟲

簡介

網絡爬蟲(又稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。

功能

按照一定地規則獲取數據,資源等

工作流程
graph TB
請求頁面-->定位資源-->獲取資源-->請求頁面
獲取資源-->整理資源-->存儲資源

爬蟲的原理非常簡單主要難點在於請求頁面定位資源

請求頁面可能遇到各種反爬機制

常見的反爬機制

請求時間間隔較短 短時間內大量請求會觸發反爬機制 一般不會一直存在,增加延時可解決 常見於小說網站,短信驗證碼等

瀏覽器UA驗證 每個瀏覽器打開頁面都有UA標識,特殊瀏覽器可能會自定義UA標示,例如微信內置瀏覽器,服務端可能會根據UA來驗證你的瀏覽器及設備返回不同頁面

referer 驗證請求來自那個url

ip限制 爬蟲運行一段時間後有被發現後封禁ip風險,可用ip代理解決

自定義驗證 請求時攜帶一個由時間戳+自定義信息生成的字段服務端驗證請求的時效性

定位資源

常用的定位資源方式有以下幾種

正則表達式 通過正則表達式匹配出固定格式的資源鏈接等

bs4 Beautiful Soup 4 是一個可以從HTML或XML文件中提取數據的Python庫

html='''
<div class="panel">
    <div class="panel-heading">
        <h4>Hello</h4>
    </div>
    <div class="panel-body">
        <ul class="list" id="list-1">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
            <li class="element">Jay</li>
        </ul>
        <ul class="list list-small" id="list-2">
            <li class="element">Foo</li>
            <li class="element">Bar</li>
        </ul>
    </div>
</div>
'''

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'lxml')
print(soup.find_all(name='ul'))
print(type(soup.find_all(name='ul')[0]))


輸出:
[<ul class="list" id="list-1">
<li class="element">Foo</li>
<li class="element">Bar</li>
<li class="element">Jay</li>
</ul>, <ul class="list list-small" id="list-2">
<li class="element">Foo</li>
<li class="element">Bar</li>
</ul>]

xpath XPath即為XML路徑語言(XML Path Language),它是一種用來確定XML文檔中某部分位置的語言

xpath是一種通用的元素定位方式,通用性類似正則表達式,能夠在各種標記語言中定位元素及屬性

xpath語法

第一個爬蟲

import requests
#導入第三方請求庫
from lxml import etree
#導入lxml庫

def get_info(text):
    html = etree.HTML(text)
    #初始化html對象
    title_list = html.xpath('//*[@id="mainContent"]/div/div[*]/div[2]/a/span/text()')
    #搜索節點
    url_list = html.xpath('//*[@id="mainContent"]/div/div[*]/div[2]/a/@href')
    for i in title_list:
        print(str(i))
        #打印標題
    for url in url_list:
        #打印鏈接
        print(url)
        
def request(url):
    req = requests.get(url)
    if req.status_code == 200:
        get_info(req.text)
    else:
        print(req.status_code)


url = 'https://www.cnblogs.com/WXGC-yang/default.html?page=1'
#程序入口
request(url)
#請求開始

測試工具

selenium Web測試

簡介

seleniumSelenium 是一個用於Web應用程序測試的工具。Selenium測試直接運行在瀏覽器中,就像真正的用戶在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。

配置

安裝Google chrome瀏覽器 正式版

根據瀏覽器版本號安裝driver

解壓後放入 /usr/bin/目錄下

安裝selenium

pip install selenium

測試登陸

from selenium import webdriver
import time
# 導入time模塊 官方模塊無需安裝

def login(mobile, passwd, sleep_time=1):
    wd = webdriver.Chrome()
    # 初始化瀏覽器
    wd.maximize_window()
    # 最大化窗口
    wd.get("https://gitee.com/")
    # 打開頁面
    time.sleep(sleep_time)
    # 延時
    wd.find_element_by_xpath('//*[@id="git-nav-user-bar"]/a[1]').click()
    # 通過xpath定位按鈕並點擊
    time.sleep(sleep_time)
    wd.find_element_by_xpath('//*[@id="user_login"]').send_keys(mobile)
    # xpath定位input輸入手機號
    time.sleep(sleep_time)
    wd.find_element_by_xpath('//*[@id="user_password"]').send_keys(passwd)
    # xpath定位input輸入密碼
    time.sleep(sleep_time)
    wd.find_element_by_xpath('//*[@id="new_user"]/div[2]/div/div/div[4]/input').click()
    # xpath定位登陸按鈕並點擊
    time.sleep(sleep_time)
    text = wd.find_element_by_xpath(
        '//*[@id="rc-users__container"]/div[1]/div[2]/div/div[1]/div[1]/div[1]/div[1]/strong/a').text
    print(text)


if __name__ == '__main__':
    mobile = '15011111111'
    passwd = '111111'
    login(mobile, passwd)
    # 調用login方法
    time.sleep(5)
    # 延時5秒後下一步

pillow 圖像處理

簡介

PIL:Python Imaging Library,已經是Python平臺事實上的圖像處理標準庫了。PIL功能非常強大,但API卻非常簡單易用。由於PIL僅支持到Python 2.7,加上年久失修,於是一群志願者在PIL的基礎上創建了兼容的版本,名字叫Pillow,支持最新Python 3.x,又加入了許多新特性,

安裝

pip install pillow

對比兩張圖片 畫出差異

from PIL import Image

img1 = Image.open('./1.png')
# 解析圖片1實例
img2 = Image.open('./2.png')
# 解析圖片2實例
width = img1.size[0]
# 獲取圖片寬度
height = img1.size[1]
# 獲取圖片高度
obj_p1 = img1.load()
# 讀取p1像素顏色
obj_p2 = img2.load()
# 讀取p2像素顏色
print(obj_p2[0, 0])
# 打印 x=1 y=2 座標的像素
p_list = []
# 新建差異點列表
difference = 40
# 差異閾值
for x in range(0, width):
    # 遍歷x軸
    for y in range(0, height):
        # 遍歷y軸
        if obj_p1[x,y] != obj_p2[x,y]:
        # 對比圖1與圖2同一個座標像素是否相同
        # if abs(obj_p1[x, y][0] - obj_p2[x, y][0]) > difference and abs(obj_p1[x, y][1] - obj_p2[x, y][1]) > difference and abs(obj_p1[x, y][2] - obj_p2[x, y][2]) > difference:
        # 優化版本 分別對比兩個點 rgb顏色差異的絕對值 是否小於差異閾值
            p_list.append([x, y])
            # 記錄差異點
new_img = Image.new('RGBA', (width, height), (255, 255, 255, 255))
# 新建使用圖1的寬高創建新圖片實例
new_img_p = new_img.load()
# 讀取新圖片像素
for i in p_list:
    # 遍歷差異點列表
    new_img_p[i[0],i[1]] = (0, 0, 0)
    # 在新圖片設置差異點顏色為黑
# 創建新圖片實例
new_img.save('./new_img.png')
# 保持新圖片

極驗 滑動驗證碼

from selenium import webdriver
from selenium.webdriver import ActionChains
import time
from PIL import Image

color_num = 40
dian_num = 10


def main():
    wd = webdriver.Chrome()
    wd.get('https://www.geetest.com/Register')
    wd.maximize_window()
    # 打開頁面
    wd.find_element_by_xpath(
        '//*[@id="gt-register-mobile"]/div/div[2]/div[1]/div[2]/div/div[2]/div[1]/input').send_keys('15011111111')
    # 定位輸入框填入手機號
    wd.find_element_by_xpath(
        '//*[@id="gt-register-mobile"]/div/div[2]/div[1]/div[2]/div/div[2]/div[2]/div[1]/div').click()
    # 定位按鈕點擊
    time.sleep(2)
    # 延時2秒等待動畫完成
    get_png(wd, '/html/body/div[3]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/div/canvas[2]', '1.png')
    # 截取第一張圖片
    run_js = js_script(wd, '/html/body/div[3]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/canvas')
    # 注入js修改元素屬性
    if run_js:
        # 驗證修改是否成功
        get_png(wd, '/html/body/div[3]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/canvas', '2.png')
        # 截取第二張圖片
    left = get_img_obj('1.png', '2.png')
    # 獲取偏移量
    slider = wd.find_element_by_xpath('/html/body/div[3]/div[2]/div[6]/div/div[1]/div[2]/div[2]')
    # 獲取滑動手柄
    ActionChains(wd).click_and_hold(slider).perform()
    # 鼠標按下
    track = get_track(left)
    for x in track:
        ActionChains(wd).move_by_offset(xoffset=x, yoffset=0).perform()
        # 鼠標移動
    ActionChains(wd).release().perform()
    # 鼠標鬆開


def js_script(wd, xpath):
    # 調用js命令設置元素屬性
    try:
        # 異常捕獲 出現異常走 except
        code = "document.evaluate('{}',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue.style.display = 'block'".format(
            xpath)
        # 生成js代碼
        wd.execute_script(code)
        # 注入js展示原圖
        return True
    except:
        return False


def get_png(wd, xpath, file_name):
    wd.find_element_by_xpath(xpath).screenshot(file_name)
    # 定位元素 截圖


def get_img_obj(file_path1, file_path2):
    img1 = Image.open(file_path1)
    img2 = Image.open(file_path2)
    # 讀取圖片
    w = img1.size[0]
    h = img1.size[1]
    # 獲取寬高
    list = []
    for x in range(w):
        for y in range(h):
            info = is_pixel_equal(img1, img2, x, y)
            if info:
                list.append(info)
    # 獲取所有差異點數組
    left = get_dian(list)

    save_img(w, h, list)
    return left


def is_pixel_equal(image1, image2, x, y):
    p1 = image1.load()[x, y]
    p2 = image2.load()[x, y]
    threshold = color_num
    # 顏色差距
    if abs(p1[0] - p2[0]) > threshold and abs(p1[1] - p2[1]) > threshold and abs(p1[1] - p2[1]) > threshold:
        return [x, y]


def get_index(file_path, x, y):
    img = Image.open(file_path, mode='r')
    rgb_img = img.load()
    index = rgb_img[x, y]
    return index


def save_img(w, h, list):
    # 獲取寬高差異點列表 生成差異圖
    img = Image.new('RGB', (w, h), (255, 255, 255))
    pixels = img.load()
    for i in list:
        pixels[i[0], i[1]] = (0, 0, 0)
    img.save('差異圖.png')


def get_track(left):
    arr = []
    num = 0
    for i in range(left):
        if num + i < left:
            arr.append(i)
            num += i
        else:
            break
    arr.append(left - num)
    return arr[::-1]
    # 返回倒序


def get_dian(arr):
    # 統計所有點座標 篩選出現次數較多的點 計算出
    key_num = {}
    for i in arr:
        if not key_num.get(i[0]):
            key_num[i[0]] = 1
        else:
            key_num[i[0]] += 1
    x_list = []
    for key in key_num:
        if key_num[key] > dian_num:
            x_list.append(key)
    bock1 = []
    for j in x_list:
        if len(bock1) != 0:
            if abs(bock1[-1] - j) < 10:
                bock1.append(j)
        else:
            bock1.append(j)
    bock2 = list(set(x_list).difference(set(bock1)))
    bock1 = sorted(bock1)
    bock2 = sorted(bock2)
    x = bock2[-1] - bock1[-1]
    return x


if __name__ == '__main__':
    try:
        main()
    except:
        main()
    time.sleep(5)

Leave a Reply

Your email address will not be published. Required fields are marked *