首页 > 编程语言 > 详细

Python高级应用程序设计任务

时间:2019-12-18 16:50:45      阅读:119      评论:0      收藏:0      [点我收藏+]

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

用Python实现一个面向主题的网络爬虫程序,并完成以下内容:

(注:每人一题,主题内容自选,所有设计内容与源代码需提交到博客园平台)

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

基于BeautifulSoup的链家网二手房信息爬取和分析

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

利用requests和BeautifulSoup进行爬取链家网信息,爬取内容包括二手房的楼房名称、价格、地址、单价、房间样式、房间规模和楼层规模,同时利用split函数进行数据信息分割,获得自己想要的数据信息。其数据特征有以下几点:

(1)分析二手房名称,对其数据进行清洗,把相同数据删除。

(2)分析二手房价格,构建数据分析模型,观察模型图价格的分布情况。

(3)分析房间样式和楼层规模,并对其进行可视化。

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

实现思路:

(1)利用requests方法请求网页,并进行验证头部信息,尝试运行返回的get值,是200则继续下一步,否则检查程序并再次尝试。

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

(3)利用find_all方法获取ul标签下的li标签。

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

(5)利用split进行数据的分割,并获取想要的数据。

(6)利用DataFrame把数据写入特定位置,为后续数据分析和数据清洗做准备。

技术难点:

(1)在爬取数据的过程中,进行翻页爬取数据时应注意利用循环和注意代码对齐。

(2)要在爬取数据之前加入请求头部信息,相当于验证身份信息,否则会出现错误提示。

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

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

打开链家网页面按F12,点击Elements,观察网页的HTML代码,可以发现所要去获取的数据都在ul标签下的li标签,同时一个房源信息对应着一个li标签。由于网页是静态的,我通过检索发现要获取的数据都可以在网页源代码中找到,因此可以利用BeautifulSoup中的find、find_all方法获取数据。

技术分享图片

 

 技术分享图片

2.Htmls页面解析

利用BeautifulSoup语法解析网站页面,并解析要获取的内容,通过解析可以发现我们想要获取的楼房名称是在li标签下,div class=”info clear”下div class=”title”下的a标签中。同理其他信息通过观察下图可得到。

技术分享图片

3.节点(标签)查找方法与遍历方法

节点的查找利用BeautifulSoup中的find、find_all方法,观察页面代码中的标签上下节点,适当使用其方法。遍历方法利用for循环实现对ul标签下li标签的全部遍历,同时实现其翻页遍历的操作。

(必要时画出节点树结构)

技术分享图片

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

#!/usr/bin/python3
#_*_coding:utf-8 _*_
#@Author:lixiaohong
#@title:爬取链家网二手房信息
#导入所需要的包
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pandas import DataFrame
import os
# 定义翻页的数量
page =100
def detail_xinx():
    # 循环实现翻页
    for i in range(page):
        url = https://quanzhou.lianjia.com/ershoufang/pg+str(i)
        try:        #异常处理
            r=requests.get(url)
            #如果状态不是200,则引发异常
            r.raise_for_status()
            #配置编码
            r.encoding=r.apparent_encoding
        except:
            print("产生异常")
        # 验证请求头部信息
        headers = {
        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400,
        Host: quanzhou.lianjia.com,
        Referer: https: // quanzhou.lianjia.com /?utm_source = sogou & utm_medium = pinzhuan & utm_term = biaoti & utm_content = biaoti & utm_campaign = sousuo
        }
        #定义数据文件名称及写入位置
        file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), lianjia_data.xlsx)
        resp = requests.get(url,headers=headers)
        #print(resp.text)   #网页内容    文本形式
        #print(resp.content.decode(‘utf-8‘))  #网页 内容   二进制形式
        html = resp.text
        # 利用BeautifulSoup语法解析网页
        soup = BeautifulSoup(html,html.parser)
        #print(soup)
        # 获取ul标签下所有的li标签
        infos = soup.find(ul,{class:sellListContent}).find_all(li)
        # print(infos)
        # 对li标签进行遍历,获取每一个li标签下的所需要数据
        for info in infos:
            #获取楼房的标题名称
            name = info.find(div,{class:title}).find(a).get_text()
            print(name)
            #获取楼房的价格(套/万元)
            price = info.find(div,{class:priceInfo}).find(div,{class:totalPrice}).find(span).get_text()
            print(price)
            #获取楼房单价(m2/元)
            totleprice =info.find(div,{class:priceInfo}).find(div,{class:unitPrice}).get_text()
            #print(totleprice)
            # 对输出的楼房单价进行分割  只获取其单价
            totle = totleprice.split(r单价)
            #print(totle)
            date0=totle[1]
            #print(date0)
            date1 =date0.split(r)
            #print(date1)
            date2 =date1[0]
            print(date2)
            #获取楼房的地址信息
            address = info.find(div,{class:flood}).find(a).get_text()
            print(address)
            #获取房间样式信息
            new = info.find(div,{class:houseInfo}).get_text()
            #print(new)
            list = new.split(r|)
            area =list[0]
            #获取房间规模信息(m2)
            print(area)
            area1=list[1]
            # print(area1)
            area2=area1.split(r)
            # print(area2)
            area3 =area2[0]
            print(area3)
            area2=list[4]
            # print(area2)
            #获取楼层规模信息
            lou=area2.split(r()
            # print(lou)
            lou1=lou[0]
            print(lou1)
            #定义一个字典用于存放创建列的名称
            infos={}
            # 定义表格中列的名称
            infos[楼房名称] = name
            infos[价格] = price
            infos[单价] = date2
            infos[地址] = address
            infos[房间样式] = area
            infos[房间规模] = area3
            infos[楼层规模] = lou1
            df = DataFrame(infos, index=[0])
            if os.path.exists(file_path):
                # 字符编码采用utf-8
                df.to_csv(file_path, header=False, index=False, mode="a+", encoding="utf_8_sig")
            else:
                df.to_csv(file_path, index=False, mode="w+", encoding="utf_8_sig")
def main():
    # 调用函数
    detail_xinx()
if __name__ == __main__:#程序执行时调用主程序main()
    main()

技术分享图片

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

#利用DataFrame进行数据加载,并查看前5行数据
import pandas as pd
df = pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
df.name="链家网泉州二手房信息"
df.head()

技术分享图片

#删除无效列
df.drop(楼层规模,axis=1,inplace=True)
df.head()

技术分享图片

#对数据进行重复值处理
df.duplicated()

技术分享图片

#把重复楼房信息删除
df =df.drop_duplicates()
df.head()

技术分享图片

#对数据进行空值处理
df[价格].isnull().value_counts()

技术分享图片

#观察数据是否需要异常值处理
df.describe()

技术分享图片

房间规模中1200有可能是一个异常值,将其用平均值表示

#把房间规模中的异常值用平均值表示
df.replace([1200.000000],df[房间规模].mean())

技术分享图片

3.文本分析(可选):jieba分词、wordcloud可视化

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

#利用regplot方法绘制回归图,并构建数据分析模型
#利用数据分析模型查看房间规模和单价之间的分布情况
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
plt.rcParams[font.sans-serif]=[SimHei]
plt.rcParams[axes.unicode_minus] = False
sns.regplot( df.房间规模,df.单价)

技术分享图片

#利用数据分析模型查看价格和单价之间的分布情况
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
plt.rcParams[font.sans-serif]=[SimHei]
plt.rcParams[axes.unicode_minus] = False
sns.regplot( df.单价,df.价格)

技术分享图片

使用直方图查看爬取的链家网泉州二手楼房的房间规模、单价、价格的分布情况。

#查看爬取楼房信息中房间规模的分布
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
sns.distplot(df[房间规模])

技术分享图片

#查看爬取楼房信息中单价的分布
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
sns.distplot(df[单价])

技术分享图片

#统计数据中房间样式的分布
import pandas as pd
df = pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
df[房间样式].value_counts()

技术分享图片

#根据对房间样式统计结果,利用柱形图进行可视化
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams[font.sans-serif]=[SimHei]
plt.rcParams[axes.unicode_minus] = False
plt.ylabel(数量)
plt.bar([3室2厅,4室2厅,2室2厅,1室1厅,2室1厅,5室2厅],[1254,606,271,194,175,152])

技术分享图片

#统计房源数量情况
import pandas as pd
df = pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
df[地址].value_counts()

技术分享图片

#利用直方图查看楼层规模的分布并可视化
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
sns.countplot(df[楼层规模])

技术分享图片

#利用散点图查看房间规模和单价之间的关系
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(H:\pycharm\lianjia/lianjia_data.xlsx)
sns.jointplot(x="房间规模",y="单价",data=df,kind=reg)

技术分享图片

5.数据持久化

  将数据存储起来,方便数据分析

技术分享图片

6.附完整程序代码

#!/usr/bin/python3
#_*_coding:utf-8 _*_
#@Author:lixiaohong
#@title:爬取链家网二手房信息
#导入所需要的包
import requests
from bs4 import BeautifulSoup
import pandas as pd
from pandas import DataFrame
import os
# 定义翻页的数量
page =100
def detail_xinx():
    # 循环实现翻页
    for i in range(page):
        url = https://quanzhou.lianjia.com/ershoufang/pg+str(i)
        try:        #异常处理
            r=requests.get(url)
            #如果状态不是200,则引发异常
            r.raise_for_status()
            #配置编码
            r.encoding=r.apparent_encoding
        except:
            print("产生异常")
        # 验证请求头部信息
        headers = {
        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3741.400 QQBrowser/10.5.3863.400,
        Host: quanzhou.lianjia.com,
        Referer: https: // quanzhou.lianjia.com /?utm_source = sogou & utm_medium = pinzhuan & utm_term = biaoti & utm_content = biaoti & utm_campaign = sousuo
        }
        #定义数据文件名称及写入位置
        file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), lianjia_data.xlsx)
        resp = requests.get(url,headers=headers)
        #print(resp.text)   #网页内容    文本形式
        #print(resp.content.decode(‘utf-8‘))  #网页 内容   二进制形式
        html = resp.text
        # 利用BeautifulSoup语法解析网页
        soup = BeautifulSoup(html,html.parser)
        #print(soup)
        # 获取ul标签下所有的li标签
        infos = soup.find(ul,{class:sellListContent}).find_all(li)
        # print(infos)
        # 对li标签进行遍历,获取每一个li标签下的所需要数据
        for info in infos:
            #获取楼房的标题名称
            name = info.find(div,{class:title}).find(a).get_text()
            print(name)
            #获取楼房的价格(套/万元)
            price = info.find(div,{class:priceInfo}).find(div,{class:totalPrice}).find(span).get_text()
            print(price)
            #获取楼房单价(m2/元)
            totleprice =info.find(div,{class:priceInfo}).find(div,{class:unitPrice}).get_text()
            #print(totleprice)
            # 对输出的楼房单价进行分割  只获取其单价
            totle = totleprice.split(r单价)
            #print(totle)
            date0=totle[1]
            #print(date0)
            date1 =date0.split(r)
            #print(date1)
            date2 =date1[0]
            print(date2)
            #获取楼房的地址信息
            address = info.find(div,{class:flood}).find(a).get_text()
            print(address)
            #获取房间样式信息
            new = info.find(div,{class:houseInfo}).get_text()
            #print(new)
            list = new.split(r|)
            area =list[0]
            #获取房间规模信息(m2)
            print(area)
            area1=list[1]
            # print(area1)
            area2=area1.split(r)
            # print(area2)
            area3 =area2[0]
            print(area3)
            area2=list[4]
            # print(area2)
            #获取楼层规模信息
            lou=area2.split(r()
            # print(lou)
            lou1=lou[0]
            print(lou1)
            #定义一个字典用于存放创建列的名称
            infos={}
            # 定义表格中列的名称
            infos[楼房名称] = name
            infos[价格] = price
            infos[单价] = date2
            infos[地址] = address
            infos[房间样式] = area
            infos[房间规模] = area3
            infos[楼层规模] = lou1
            df = DataFrame(infos, index=[0])
            if os.path.exists(file_path):
                # 字符编码采用utf-8
                df.to_csv(file_path, header=False, index=False, mode="a+", encoding="utf_8_sig")
            else:
                df.to_csv(file_path, index=False, mode="w+", encoding="utf_8_sig")
def main():
    # 调用函数
    detail_xinx()
if __name__ == __main__:#程序执行时调用主程序main()
    main()

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

(1)链家网泉州地区的二手楼房单价大概集中在9000元/m2—12000元/m2。

(2)链家网泉州地区的二手楼房的房间规模大概分布在110平方米左右。

(3)链家网泉州地区的二手楼房一套价格大概在150万左右。

(4)泉州地区的二手楼房的房间样式主要以3室2厅、4室2厅、2室2厅三种类型为主。

(5)泉州地区的嘉琳广场 、泰禾首府、中航城天悦、新城华庭房源数量较其他地方多。 

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

   经过这段时间对爬虫知识的学习,我对爬虫所使用的requests库和BeautifulSoup库有初步的认识,对爬虫的流程也有初步的了解。希望自己能坚持学习,不断进步。

Python高级应用程序设计任务

原文:https://www.cnblogs.com/lixiaohong/p/12002029.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!