码迷,mamicode.com
首页 > 编程语言 > 详细

Python高级应用程序设计任务

时间:2019-12-21 18:49:30      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:dia   app   bsp   alt   价格   sig   爬取图片   散点图   详情   

Python高级应用程序设计任务要求

用Python实现一个面向主题的网络爬虫程序,并完成以下内容:
(注:每人一题,主题内容自选,所有设计内容与源代码需提交到博客园平台)

一、主题式网络爬虫设计方案(15分)
1.主题式网络爬虫名称

基于requests的携程旅游(北京景点)爬取和分析

2.主题式网络爬虫爬取的内容与数据特征分析

爬取内容包括景点的名称、评论量、分数。其数据特征有以下几点:

(1)分析景点、评分、评论数据,并进行清洗

(2)分析景点和评论数的关系,构建数据分析模型,观察模型图价格的分布情况。

3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)

实现思路:

(1)利用requests方法请求网页。

(2)利用lxml进行网页解析,同时利用其语法获取需要的数据信息。

(3)利用循环实现翻页获取数据。

技术难点:

(1)要在爬取数据之前加入请求头部信息,否则会出现错误提示。

(2)注意要获取的数据在哪一个标签下,利用F12进行数据检查和分析所要爬取的数据特征。

二、主题页面的结构特征分析(15分)
1.主题页面的结构特征

查看源代码 li 对应着每一个攻略信息,都是静态页面,无ajax、js产生的动态数据。

技术图片
2.Htmls页面解析

通过解析可以发现我们想要获取的楼房名称是在li标签下,dl下的a标签中。
3.节点(标签)查找方法与遍历方法
(必要时画出节点树结构)

三、网络爬虫程序设计(60分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后面提供输出结果的截图。
1.数据爬取与采集

def pachong():
    for i in range(1,10):

        url = https://you.ctrip.com/searchsite/sight/?query=%e5%8c%97%e4%ba%ac&isAnswered=&isRecommended=&publishDate=&PageNo=+str(i)
        res = get_tree(url)
        # 获取景点的列表
        li_list =  res.xpath(//ul[@class="jingdian-ul cf"]/li)
        # 循环列表,拿取每一个数据
        for li in li_list:
            dic = {}
            # # 景点名
            name = li.xpath(./dl/dt/a[1]/text())
            dic[name] = name[0]


            # 保存景点图片,以景点名命名
            picture = li.xpath(./a/img/@src)[0]
            pic_url = picture
            # 因为有些图片地址路径不全,价格判断
            if http not in picture:
                pic_url = https:+picture
            pic = requests.get(pic_url)
            dir = f./{name[0]}.png
            


            pinglun = li.xpath(./dl/dd/a/text())
            # 评论数量
            dic[pinglun] = pinglun[0]
            xq_url = li.xpath(./a/@href)
            # 详情页
            xq_url = https://you.ctrip.com+xq_url[0]
            res1 = get_tree(xq_url)
            # 因为评分分两种格式,使用if判断拿取
            fen = res1.xpath(//span[@class="score"]/b/text())
            if fen ==[]:
                fen1 = res1.xpath(//div[@class="score"]/span/i/text())
                dic[pingfen] = fen1[0]
            else:
                dic[pingfen] = fen[0]

            #保存数据
            with open(景区.txt,a,encoding=utf8) as fp2:
                fp2.write(str(dic))
                fp2.write(\n)
            print(dic)
            time.sleep(1)

 


2.对数据进行清洗和处理

# 清洗数据
    name = []
    pinglun = []
    pingfen = []
    for i in data:
        lst1 = i.split(,)
        dic = {}
        for j in range(len(lst1)):
            dic[j] = lst1[j].split(:)[1].strip().replace("", "").replace(}, ‘‘)
        name.append(dic[0])
        pinglun.append(int(dic[1].replace(条点评, ‘‘)))
        pingfen.append(float(dic[2]))

 


3.文本分析(可选):jieba分词、wordcloud可视化
4.数据分析与可视化
(例如:数据柱形图、直方图、散点图、盒图、分布图、数据回归分析等)

技术图片技术图片
5.数据持久化

技术图片
6.附完整程序代码

import requests
from lxml import etree
import math
import time
import matplotlib.pyplot as plt
import pandas as pd
import json

# 返回xpath数据
def get_tree(url):
    # 获取 网页内容,返回 xpath 数据
    headers = {
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
    }
    
    res = requests.get(url=url,headers=headers).content.decode(utf-8)
    # 保存网页,方便查看内容
    # with open(‘qu.html‘,‘w‘,encoding=‘utf8‘)as fp:
    #     fp.write(res)
    res = etree.HTML(res)
    return res

# 爬虫函数
def pachong():
    for i in range(1,10):

        url = https://you.ctrip.com/searchsite/sight/?query=%e5%8c%97%e4%ba%ac&isAnswered=&isRecommended=&publishDate=&PageNo=+str(i)
        res = get_tree(url)
        # 获取景点的列表
        li_list =  res.xpath(//ul[@class="jingdian-ul cf"]/li)
        # 循环列表,拿取每一个数据
        for li in li_list:
            dic = {}
            # # 景点名
            name = li.xpath(./dl/dt/a[1]/text())
            dic[name] = name[0]


            # 保存景点图片,以景点名命名
            picture = li.xpath(./a/img/@src)[0]
            pic_url = picture
            # 因为有些图片地址路径不全,价格判断
            if http not in picture:
                pic_url = https:+picture
            pic = requests.get(pic_url)
            dir = f./{name[0]}.png
            


            pinglun = li.xpath(./dl/dd/a/text())
            # 评论数量
            dic[pinglun] = pinglun[0]
            xq_url = li.xpath(./a/@href)
            # 详情页
            xq_url = https://you.ctrip.com+xq_url[0]
            res1 = get_tree(xq_url)
            # 因为评分分两种格式,使用if判断拿取
            fen = res1.xpath(//span[@class="score"]/b/text())
            if fen ==[]:
                fen1 = res1.xpath(//div[@class="score"]/span/i/text())
                dic[pingfen] = fen1[0]
            else:
                dic[pingfen] = fen[0]

            #保存数据
            with open(景区.txt,a,encoding=utf8) as fp2:
                fp2.write(str(dic))
                fp2.write(\n)
            print(dic)
            time.sleep(1)
# 评分图绘制
def pingfentu():

    # 读数据
    with open(景区.txt, r, encoding=utf8)as fp:
        data = fp.read()

    data = data.split(\n)

    # 清洗数据
    name = []
    pinglun = []
    pingfen = []
    for i in data:
        lst1 = i.split(,)
        dic = {}
        for j in range(len(lst1)):
            dic[j] = lst1[j].split(:)[1].strip().replace("", "").replace(}, ‘‘)
        name.append(dic[0])
        pinglun.append(int(dic[1].replace(条点评, ‘‘)))
        pingfen.append(float(dic[2]))

    data = {名字: name, 评论数: pinglun, 评分: pingfen}
    #
    # 转为DataFrane 格式数据
    df1 = pd.DataFrame(data)

    # 分析及绘图
    # ---------------------------------
    # 评分图
    plt.figure()
    # 修改默认字体
    plt.rcParams[font.sans-serif] = SimHei
    # 正常显示符号,解决方块问题
    plt.rcParams[axes.unicode_minus] = False
    pingfen1 = [i for i in df1[评分]]
    group = [4.0 + i / 10 for i in range(11)]
    plt.hist(pingfen1, group, color=r)
    plt.xlabel(评分)
    plt.ylabel(数量, rotation=0)
    plt.savefig(评分图.png)
    plt.show()
# 评论图绘制
def pingluntu():
    with open(景区.txt, r, encoding=utf8)as fp:
        data = fp.read()

    data = data.split(\n)

    # 清洗数据
    name = []
    pinglun = []
    pingfen = []
    for i in data:
        lst1 = i.split(,)
        dic = {}
        for j in range(len(lst1)):
            dic[j] = lst1[j].split(:)[1].strip().replace("", "").replace(}, ‘‘)
        name.append(dic[0])
        pinglun.append(int(dic[1].replace(条点评, ‘‘)))
        pingfen.append(float(dic[2]))

    data = {名字: name, 评论数: pinglun, 评分: pingfen}
    #
    # 转为DataFrane 格式数据
    df1 = pd.DataFrame(data)
    # 评论数前10绘图
    df1_10 = df1.sort_values(by=评论数, ascending=False)[:20]

    plt.figure()
    plt.rcParams[font.sans-serif] = SimHei
    # 正常显示符号,解决方块问题
    plt.rcParams[axes.unicode_minus] = False
    x = [i for i in range(10)]
    plt.plot(x, df1_10[评论数][:10], color=g, linestyle=-., marker=p, markerfacecolor=r)
    plt.xticks(x, df1_10[名字][:10], rotation=-45)
    for i in range(10):
        p = df1_10[评论数][i]
        plt.text(x[i], p + 100, %d条评论 % p, horizontalalignment=center)
    plt.savefig(评论图.png)
    plt.show()

if __name__ == __main__:
    pachong()
    pingfentu()
    pingluntu()

 

四、结论(10分)
1.经过对主题数据的分析与可视化,可以得到哪些结论?

排除评论过少的景点,评分高的景点评论越多 

2.对本次程序设计任务完成的情况做一个简单的小结。

经过这段时间对爬虫知识的学习,我对爬虫所使用的requests库、BeautifulSoup库、scrapy框架、lxml库有初步的认识,对爬虫的流程也有初步的了解。虽然这次爬取图片出了许多问题直到最后也没解决,希望自己以后能够爬取动态网页。

import requests
from lxml import etree
import math
import time
import matplotlib.pyplot as plt
import pandas as pd
import json

# 返回xpath数据
def get_tree(url):
    # 获取 网页内容,返回 xpath 数据
    headers = {
‘user-agent‘:‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36‘
    }
    
    res = requests.get(url=url,headers=headers).content.decode(‘utf-8‘)
    # 保存网页,方便查看内容
    # with open(‘qu.html‘,‘w‘,encoding=‘utf8‘)as fp:
    #     fp.write(res)
    res = etree.HTML(res)
    return res

# 爬虫函数
def pachong():
    for i in range(1,10):

        url = ‘https://you.ctrip.com/searchsite/sight/?query=%e5%8c%97%e4%ba%ac&isAnswered=&isRecommended=&publishDate=&PageNo=‘+str(i)
        res = get_tree(url)
        # 获取景点的列表
        li_list =  res.xpath(‘//ul[@class="jingdian-ul cf"]/li‘)
        # 循环列表,拿取每一个数据
        for li in li_list:
            dic = {}
            # # 景点名
            name = li.xpath(‘./dl/dt/a[1]/text()‘)
            dic[‘name‘] = name[0]


            # 保存景点图片,以景点名命名
            picture = li.xpath(‘./a/img/@src‘)[0]
            pic_url = picture
            # 因为有些图片地址路径不全,价格判断
            if ‘http‘ not in picture:
                pic_url = ‘https:‘+picture
            pic = requests.get(pic_url)
            dir = f‘./{name[0]}.png‘
            


            pinglun = li.xpath(‘./dl/dd/a/text()‘)
            # 评论数量
            dic[‘pinglun‘] = pinglun[0]
            xq_url = li.xpath(‘./a/@href‘)
            # 详情页
            xq_url = ‘https://you.ctrip.com‘+xq_url[0]
            res1 = get_tree(xq_url)
            # 因为评分分两种格式,使用if判断拿取
            fen = res1.xpath(‘//span[@class="score"]/b/text()‘)
            if fen ==[]:
                fen1 = res1.xpath(‘//div[@class="score"]/span/i/text()‘)
                dic[‘pingfen‘] = fen1[0]
            else:
                dic[‘pingfen‘] = fen[0]

            #保存数据
            with open(‘景区.txt‘,‘a‘,encoding=‘utf8‘as fp2:
                fp2.write(str(dic))
                fp2.write(\n)
            print(dic)
            time.sleep(1)
# 评分图绘制
def pingfentu():

    # 读数据
    with open(‘景区.txt‘‘r‘encoding=‘utf8‘)as fp:
        data = fp.read()

    data = data.split(\n)

    # 清洗数据
    name = []
    pinglun = []
    pingfen = []
    for i in data:
        lst1 = i.split(‘,‘)
        dic = {}
        for j in range(len(lst1)):
            dic[j] = lst1[j].split(‘:‘)[1].strip().replace("‘""").replace(‘}‘‘‘)
        name.append(dic[0])
        pinglun.append(int(dic[1].replace(‘条点评‘‘‘)))
        pingfen.append(float(dic[2]))

    data = {‘名字‘: name, ‘评论数‘: pinglun, ‘评分‘: pingfen}
    #
    # 转为DataFrane 格式数据
    df1 = pd.DataFrame(data)

    # 分析及绘图
    # ---------------------------------
    # 评分图
    plt.figure()
    # 修改默认字体
    plt.rcParams[‘font.sans-serif‘] = ‘SimHei‘
    # 正常显示符号,解决方块问题
    plt.rcParams[‘axes.unicode_minus‘] = False
    pingfen1 = [i for i in df1[‘评分‘]]
    group = [4.0 + i / 10 for i in range(11)]
    plt.hist(pingfen1, group, color=‘r‘)
    plt.xlabel(‘评分‘)
    plt.ylabel(‘数量‘rotation=0)
    plt.savefig(‘评分图.png‘)
    plt.show()
# 评论图绘制
def pingluntu():
    with open(‘景区.txt‘‘r‘encoding=‘utf8‘)as fp:
        data = fp.read()

    data = data.split(\n)

    # 清洗数据
    name = []
    pinglun = []
    pingfen = []
    for i in data:
        lst1 = i.split(‘,‘)
        dic = {}
        for j in range(len(lst1)):
            dic[j] = lst1[j].split(‘:‘)[1].strip().replace("‘""").replace(‘}‘‘‘)
        name.append(dic[0])
        pinglun.append(int(dic[1].replace(‘条点评‘‘‘)))
        pingfen.append(float(dic[2]))

    data = {‘名字‘: name, ‘评论数‘: pinglun, ‘评分‘: pingfen}
    #
    # 转为DataFrane 格式数据
    df1 = pd.DataFrame(data)
    # 评论数前10绘图
    df1_10 = df1.sort_values(by=‘评论数‘ascending=False)[:20]

    plt.figure()
    plt.rcParams[‘font.sans-serif‘] = ‘SimHei‘
    # 正常显示符号,解决方块问题
    plt.rcParams[‘axes.unicode_minus‘] = False
    x = [i for i in range(10)]
    plt.plot(x, df1_10[‘评论数‘][:10], color=‘g‘linestyle=‘-.‘marker=‘p‘markerfacecolor=‘r‘)
    plt.xticks(x, df1_10[‘名字‘][:10], rotation=-45)
    for i in range(10):
        p = df1_10[‘评论数‘][i]
        plt.text(x[i], p + 100%d条评论‘ % p, horizontalalignment=‘center‘)
    plt.savefig(‘评论图.png‘)
    plt.show()

if __name__ == ‘__main__‘:
    pachong()
    pingfentu()
    pingluntu()

Python高级应用程序设计任务

标签:dia   app   bsp   alt   价格   sig   爬取图片   散点图   详情   

原文地址:https://www.cnblogs.com/lidating/p/12077775.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!