Python---数据预处理三

11.网页数据解析
# 导入库
import requests  # 用于发出HTML请求
from bs4 import BeautifulSoup  # 用于HTML格式化处理
import pandas as pd  # 格式化数据


class WebParse:
    # 初始化对象
    def __init__(self, headers):
        self.headers = headers
        self.article_list = []
        self.home_page = 'http://www.dataivy.cn/'
        self.nav_page = 'http://www.dataivy.cn/page/{0}/'
        self.art_title = None
        self.art_time = None
        self.art_cat = None
        self.art_tags = None

    # 获取页面数量
    def get_max_page_number(self):
        res = requests.get(self.home_page, headers=self.headers)  # 发送请求
        html = res.text  # 获得请求中的返回文本信息
        html_soup = BeautifulSoup(html, "html.parser")  # 建立soup对象
        page_num_code = html_soup.findAll('a', attrs={"class": "page-numbers"})
        num_sets = [re.findall(r'(\d+)', i.text)
                    for i in page_num_code]  # 获得页面字符串类别
        num_int = [int(i[0]) for i in num_sets if len(i) > 0]  # 获得数值页码
        return max(num_int)  # 最大页码

    # 获得文章列表
    def find_all_articles(self, i):
        url = self.nav_page.format(i)
        res = requests.get(url, headers=headers)  # 发送请求
        html = res.text  # 获得请求中的返回文本信息
        html_soup = BeautifulSoup(html, "html.parser")  # 建立soup对象,用于处理HTML
        self.article_list = html_soup.findAll('article')

    # 解析单文章
    def parse_single_article(self, article):
        self.art_title = article.find('h2', attrs={"class": "entry-title"}).text
        self.art_time = article.find('time', attrs={
            "class": {"entry-date published", "entry-date published updated"}}).text
        self.art_cat = article.find('a', attrs={"rel": "category tag"}).text
        tags_code = article.find('span', attrs={"class": "tags-links"})
        self.art_tags = '' if tags_code is None else WebParse._parse_tags(self, tags_code)

    # 内部用解析tag函数
    def _parse_tags(self, tags_code):
        tag_strs = ''
        for i in tags_code.findAll('a'):
            tag_strs = tag_strs + '/' + i.text
        return tag_strs

    # 格式化数据
    def format_data(self):
        return [self.art_title,
                self.art_time,
                self.art_cat,
                self.art_tags]


if __name__ == '__main__':
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}  # 定义头信息
    data_cols = ['title', 'time', 'cat', 'tags']
    app = WebParse(headers)
    max_num = app.get_max_page_number()
    data_list = []
    for ind in range(max_num):
        app.find_all_articles(ind + 1)  # ind从0开始,因此要加1
        for article in app.article_list:
            app.parse_single_article(article)
            data_list.append(app.format_data())
    data_pd = pd.DataFrame(data_list, columns=data_cols)
    print(data_pd.head(2))

12.网络用户日志解析
# 导入库
import gzip
import re
import time


# 判断是否为爬虫记录
def is_spider(log_record, spiders):
    detect_result = [True if log_record.find(spider) == -1 else False for spider in spiders]
    is_exist = True if all(detect_result) else False
    return is_exist


# 判断是否为UA记录
def is_ua_record(log_record):
    is_ua = True if log_record.find('GET /__ua.gif?') != -1 else False
    return is_ua


# 解析每条日志数据
def split_ua_data(line):
    # 定义不同日志分割的正则表达式
    ip_pat = '[\d.]*'  # 定义IP规则,例如203.208.60.230
    time_pat = '\[[^\[\]]*\]'  # 定义时间规则,例如[02/Mar/2016:14:00:23 +0800]
    request_pat = '\"[^\"]*\"'  # 定义请求规则
    status_pat = '\d+'  # 定义返回的状态码规则,例如200
    bytes_pat = '\d+'  # 返回的字节数,例如326
    refer_pat = '\"[^\"]*\"'  # 定义refer规则
    user_agent_pat = '\"[^\"]*\"'  # 定义user agnet规则
    # 原理:主要通过空格和-来区分各不同项目,各项目内部写各自的匹配表达式
    re_pattern = re.compile('(%s)\ -\ -\ (%s)\ (%s)\ (%s)\ (%s)\ (%s)\ (%s)' % (
        ip_pat, time_pat, request_pat, status_pat, bytes_pat, refer_pat, user_agent_pat),
                            re.VERBOSE)  # 完整表达式模式
    matchs = re_pattern.match(line)  # 匹配
    if matchs != None:  # 如果不为空
        allGroups = matchs.groups()  # 获得所有匹配的列表
        return allGroups[0], allGroups[1], allGroups[2], allGroups[3], allGroups[4], allGroups[5], allGroups[6]
    else:  # 否则返回空
        return '', '', '', '', '', '', ''


# 读取日志数据
def get_ua_data(file, spiders):
    ua_data = []
    with gzip.open(file, 'rt') as fn:  # 打开要读取的日志文件对象
        content = fn.readlines()  # 以列表形式读取日志数据
    for single_log in content:  # 循环判断每天记录
        rule1 = is_spider(single_log, spiders)
        rule2 = is_ua_record(single_log)
        if rule1 and rule2:  # 如果同时符合2条规则,则执行
            ua_data.append(split_ua_data(single_log))
    ua_pd = pd.DataFrame(ua_data)
    return ua_pd


# 主程序
if __name__ == '__main__':
    file = 'dataivy.cn-Feb-2018.gz'  # 定义原始日志的文件名
    spiders = [
        'AhrefsBot',
        'archive.org_bot',
        'baiduspider',
        'Baiduspider',
        'bingbot',
        'DeuSu',
        'DotBot',
        'Googlebot',
        'iaskspider',
        'MJ12bot',
        'msnbot',
        'Slurp',
        'Sogou web spider',
        'Sogou Push Spider',
        'SputnikBot',
        'Yahoo! Slurp China',
        'Yahoo! Slurp',
        'YisouSpider',
        'YodaoBot',
        'bot.html'
    ]
    ua_pd = get_ua_data(file, spiders)
    ua_pd.columns = ['ip_add', 'requet_time', 'request_info', 'status', 'bytes_info', 'referral', 'ua']
    output_file = 'ua_result_{0}.xlsx'.format(time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())))
    ua_pd.to_excel(output_file, index=False)
    print('excel file {0} generated!'.format(output_file))

13.图像的基本预处理
import cv2  # 导入图像处理库
import numpy as np  # 导入numpy库
from matplotlib import pyplot as plt  # 导入展示库


# 展示图像模块
def img_show(img_name, img):
    cv2.imshow(img_name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


# 原始图像
img_file = 'sudoku.png'  # 定义原始数据文件
img = cv2.imread(img_file)  # 以彩色模式读取图像文件
rows, cols, ch = img.shape  # 获取图像形状
img_show('raw img', img)  # 展示彩色图像

# 图像缩放
img_scale = cv2.resize(img, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_CUBIC)  # 图像缩放
img_show('scale img', img_scale)  # 展示缩放后的图像

# 图像平移
M = np.float32([[1, 0, 100], [0, 1, 50]])  # 定义平移中心
img_transform = cv2.warpAffine(img, M, (cols, rows))  # 平移图像
img_show('transform img', img_transform)  # 展示平移后的图像

# 图像旋转
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 0.6)  # 定义旋转中心
img_rotation = cv2.warpAffine(img, M, (cols, rows))  # 第一个参数为旋转中心,第二个为旋转角度,第三个为旋转后的缩放因子
img_show('rotation img', img_rotation)  # 展示旋转后的图像

# 透视变换
pts1 = np.float32([[76, 89], [490, 74], [37, 515], [520, 522]])  # 定义变换前的四个校准点
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])  # 定义变换后的四个角点
M = cv2.getPerspectiveTransform(pts1, pts2)  # 定义变换中心点
img_perspective = cv2.warpPerspective(img, M, (300, 300))  # 透视变换
img_show('perspective img', img_perspective)  # 展示透视变换后的图像

# 转换为灰度图像
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 图像转灰度
img_show('gray img', img_gray)  # 展示灰度图像

# 边缘检测
img_edges = cv2.Canny(img, 100, 200)  # 检测图像边缘
img_show('edges img', img_edges)  # 展示图像边缘

# 图像二值化
ret, th1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)  # 简单阀值
th2 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11,
                            2)  # 自适应均值阀值
th3 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11,
                            2)  # 自适应高斯阀值
titles = ['Gray Image', 'Global Thresholding (v = 127)',
          'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']  # 定义图像标题
images = [img_gray, th1, th2, th3]  # 定义图像集
for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')  # 以灰度模式展示每个子网格的图像
    plt.title(titles[i])  # 设置每个自网格标题
    plt.xticks([]), plt.yticks([])  # 设置x轴和y轴标题

# 图像平滑
kernel = np.ones((5, 5), np.float32) / 25  # 设置平滑内核大小
img_smoth_filter2D = cv2.filter2D(img, -1, kernel)  # 2D卷积法
img_smoth_blur = cv2.blur(img, (5, 5))  # 平均法
img_smoth_gaussianblur = cv2.GaussianBlur(img, (5, 5), 0)  # 高斯模糊
img_smoth_medianblur = cv2.medianBlur(img, 5)  # 中值法
titles = ['filter2D', 'blur', 'GaussianBlur', 'medianBlur']  # 定义标题集
images = [img_smoth_filter2D, img_smoth_blur, img_smoth_gaussianblur, img_smoth_medianblur]  # 定义图像集
for i in range(4):
    plt.subplot(1, 4, i + 1),
    plt.imshow(images[i], 'gray')  # 以灰度模式展示每个子网格的图像
    plt.title(titles[i])  # 设置每个自网格标题
    plt.xticks([]), plt.yticks([])  # 设置x轴和y轴标题

# 形态学处理
img2 = cv2.imread('j.png', 0)  # 以灰度模式读取图像
kernel = np.ones((5, 5), np.uint8)  # 设置形态学处理内核大小
erosion = cv2.erode(img2, kernel, iterations=1)  # 腐蚀
dilation = cv2.dilate(img2, kernel, iterations=1)  # 膨胀
plt.subplot(1, 3, 1), plt.imshow(img2, 'gray')  # 设置自网格1图像
plt.subplot(1, 3, 2), plt.imshow(erosion, 'gray')  # 设置自网格2图像
plt.subplot(1, 3, 3), plt.imshow(dilation, 'gray')  # 设置自网格3图像

14.图像的基本预处理
# 导入库
import pandas as pd
import jieba  # 结巴分词
from sklearn.feature_extraction.text import TfidfVectorizer  # 基于TF-IDF的词频转向量库


# 分词函数
def jieba_cut(string):
    return list(jieba.cut(string))  # 精确模式分词


# 读取自然语言文件和停用词
with open('text.txt', encoding='utf8') as fn1, open('stop_words.txt', encoding='utf8') as fn2:
    string_lines = fn1.read()
    stop_words = fn2.read()
string_lines = string_lines.split('\n')
stop_words = stop_words.split('\n')

# 中文分词
seg_list = list(map(jieba_cut, string_lines))  # 存储所有分词结果
for i in range(3):  # 打印输出第一行的前5条数据
    print(seg_list[1][i])

# word to vector
vectorizer = TfidfVectorizer(stop_words=stop_words, tokenizer=jieba_cut)  # 创建词向量模型
vector_value = vectorizer.fit_transform(string_lines).toarray()  # 将文本数据转换为向量空间模型
vector = vectorizer.get_feature_names()  # 获得词向量
vector_pd = pd.DataFrame(vector_value, columns=vector)  # 创建用于展示的数据框
print(vector_pd.head(1))  # 打印输出第一条数据

你可能感兴趣的:(数据化运营,Python,数据分析)