精华内容
下载资源
问答
  • 爬取北京二手房数据信息python代码: # coding : utf-8 import requests from bs4 import BeautifulSoup as bs from tqdm import tqdm from multiprocessing import Pool import time import os import re import...

    数据爬取

    爬取北京二手房数据信息python代码:

    # coding : utf-8
    
    from requests import get
    from bs4 import BeautifulSoup as bs
    from tqdm import tqdm
    from multiprocessing import Pool
    from time import time
    from os import listdir
    from csv import writer
    import re
    
    def url_spider(url):
        """
        爬取网页信息
        """
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36 LBBROWSER'}
        try:
            response = get(url, headers=headers, verify=True, timeout=10)
            if response.status_code == 200:
                soup = bs(response.text, features="html.parser")
                return soup
            else:
                print("\n\n*** (%s)请求状态异常 ***\n\n" % url)
    
                return None  # 状态码非200则返回空值
        except Exception as e:
            print('\n\n*** Requests.get(%s) gets wrong! ***\nThe program will try again later.\n\n' % url)
            print(e)
            return None
    
    def url_list(n1, n2):
        """
        获取具体房子URL信息,建立URL池
        """
        lis = []
        print('\n******  获取房子URL信息中...')
        for i in range(n1,n2+1):
            url = 'https://bj.lianjia.com/ershoufang/pg' + str(i) + '/'
            print('******  正在获取第{}页的房子URL信息'.format(i))
            res = url_spider(url)
            if res is not None:
                infos = res.find_all('div', class_="item")
                for info in infos:
                    href = info.find("a", class_="title").get("href")
                    lis.append(href)
            else:
                print('\n******  获取房子URL信息失败')
    
         #   time.sleep(5)
        # URL写入文件
        if 'urls.txt' not in listdir():
            with open('urls.txt', 'a', encoding="utf-8") as f:
                for i in lis:
                    f.write(i+"\n")
                f.close()
        else:
            with open('urls.txt', 'r', encoding="utf-8") as f:
                fis = f.readlines()
                f.close()
            with open('urls.txt', 'a', encoding="utf-8") as f:
                for i in lis:
                    k = i+"\n"
                    if k not in fis:
                        f.write(k)
                f.close()
    
    def soup_parser(soup):
        """
        获取房子详细信息,并保存为csv文件
        """
        data = [soup.find('div', class_="communityName").find('a', class_="info").text,
                soup.find('div', class_="areaName").find('span', class_="info").text,
                soup.find('span', class_="total").text,
                soup.find('span', class_="unitPriceValue").text
                ]
        base = soup.find('div', class_="base").find_all('li')
        tran = soup.find('div', class_="transaction").find_all('li')
        for i in base:
            data.append(i.text)
        for i in tran:
            data.append(i.text)
        # time.sleep(3)
        return data
    
    def data_proce(data, label):
        """
        处理数据格式
        """
        # print(data)
        lis = []
        for i in data:
            a = i.replace('\xa0','_').replace('\n','').replace('  ','').replace(' ','_')
            st = a[:4]
            if st in label:
                a = a.replace(st,'')
            lis.append(a)
        return lis
    
    def write_csv(data_lis):
        """
        写入csv文件
        """
        label = ["小区名称", "所在区域", "总价", "单价", "房屋户型", "所在楼层",
                 "建筑面积", "户型结构", "套内面积", "建筑类型", "房屋朝向", "建筑结构",
                 "装修情况", "梯户比例", "供暖方式", "配备电梯", "挂牌时间", "交易权属",
                 "上次交易", "房屋用途", "房屋年限", "房权所属", "抵押信息", "房本备件"]
        data_lis = data_proce(data_lis, label)
        if 'all_data.csv' not in listdir():
            with open('all_data.csv', 'a', newline='', encoding='utf-8') as f:
                writer = writer(f, delimiter=',')
                writer.writerow(label)
                writer.writerow(data_lis)
                f.close()
        else:
            with open('all_data.csv', 'a', newline='', encoding='utf-8') as f:
                writer = writer(f, delimiter=',')
                writer.writerow(data_lis)
                f.close()
    
    def main(url):
        """
        :return:
        """
        url = url.replace('\n', '').replace('\t', '')
        res = url_spider(url)
        if res is not None:
            print("******  正在获取{}的房子信息".format(url))
            data_csv = soup_parser(res)
            write_csv(data_csv)
        else:
            print("******  获取{}的房子信息失败".format(url))
    
    
    def async_main(urls):
        """
        :return:
        """
        p = Pool(4)
        for url in urls:
            p.apply_async(main, (url,))
        p.close()
        p.join()
    
    
    if __name__ == "__main__":
        start = time()
        n = input('请输入数据集范围(如1-10):').split("-")
        (n1, n2) = (int(n[0]), int(n[1]))
        url_list(n1, n2)  # 爬取房子URL信息
        with open('urls.txt', 'r', encoding="utf-8") as f:
            urls = f.readlines()
            f.close()
        print('\n******  共获取到{}套房子信息'.format(len(urls)))
        # main(urls[0])
        async_main(urls)
    
        end = time()
        print("所用时间: {}".format(end - start))
    

    展开全文
  • 原标题:Python 爬取北京二手房数据,分析北漂族买得起房吗? | 附完整源码 房价高是北漂们一直关心的话题,本文就对北京的二手房数据进行了分析。本文主要分为两部分:Python爬取赶集网北京二手房数据,R对爬取的...

    原标题:Python 爬取北京二手房数据,分析北漂族买得起房吗? | 附完整源码

    ea15841aacbc4376b2dd66d0ea14b5f3.jpeg

    房价高是北漂们一直关心的话题,本文就对北京的二手房数据进行了分析。

    本文主要分为两部分:Python爬取赶集网北京二手房数据,R对爬取的二手房房价做线性回归分析,适合刚刚接触Python&R的同学们学习参考。

    Python爬取赶集网北京二手房数据

    入门爬虫一个月,所以对每一个网站都使用了Xpath、Beautiful Soup、正则三种方法分别爬取,用于练习巩固。数据来源如下:

    9f49d4e2ef8649fdb15c631fab344641.jpeg

    Xpath爬取:

    这里主要解决运用Xpath如何判断某些元素是否存在的问题,比如如果房屋没有装修信息,不加上判断,某些元素不存在就会导致爬取中断。

    importrequests

    fromlxml importetree

    fromrequests.exceptions importRequestException

    importmultiprocessing

    importtime

    headers = {

    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

    defget_one_page(url):

    try:

    response = requests.get(url, headers=headers)

    ifresponse.status_code == 200:

    returnresponse.text

    returnNone

    exceptRequestException:

    returnNone

    defparse_one_page(content):

    try:

    selector = etree.HTML(content)

    ALL = selector.xpath( '//*[@id="f_mew_list"]/div[6]/div[1]/div[3]/div[1]/div')

    fordiv inALL:

    yield{

    'Name': div.xpath( 'dl/dd[1]/a/text()')[ 0],

    'Type': div.xpath( 'dl/dd[2]/span[1]/text()')[ 0],

    'Area': div.xpath( 'dl/dd[2]/span[3]/text()')[ 0],

    'Towards': div.xpath( 'dl/dd[2]/span[5]/text()')[ 0],

    'Floor': div.xpath( 'dl/dd[2]/span[7]/text()')[ 0].strip().replace( 'n', ""),

    'Decorate': div.xpath( 'dl/dd[2]/span[9]/text()')[ 0],

    #地址需要特殊处理一下

    'Address': div.xpath( 'dl/dd[3]//text()')[ 1]+div.xpath( 'dl/dd[3]//text()')[ 3].replace( 'n', '')+div.xpath( 'dl/dd[3]//text()')[ 4].strip(),

    'TotalPrice': div.xpath( 'dl/dd[5]/div[1]/span[1]/text()')[ 0] + div.xpath( 'dl/dd[5]/div[1]/span[2]/text()')[ 0],

    'Price': div.xpath( 'dl/dd[5]/div[2]/text()')[ 0]

    }

    ifdiv[ 'Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price'] == None: ##这里加上判断,如果其中一个元素为空,则输出None

    returnNone

    exceptException:

    returnNone

    defmain():

    fori inrange( 1, 500): #这里设置爬取500页数据,在数据范围内,大家可以自设置爬取的量

    url = 'http://bj.ganji.com/fang5/o{}/'.format(i)

    content = get_one_page(url)

    print( '第{}页抓取完毕'.format(i))

    fordiv inparse_one_page(content):

    print(div)

    if__name__ == '__main__':

    main()

    Beautiful Soup爬取:

    importrequests

    importre

    fromrequests.exceptions importRequestException

    frombs4 importBeautifulSoup

    importcsv

    importtime

    headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

    defget_one_page(url):

    try:

    response = requests.get(url,headers = headers)

    ifresponse.status_code == 200:

    returnresponse.text

    returnNone

    exceptRequestException:

    returnNone

    defparse_one_page(content):

    try:

    soup = BeautifulSoup(content, 'html.parser')

    items = soup.find( 'div',class_=re.compile( 'js-tips-list'))

    fordiv initems.find_all( 'div',class_=re.compile( 'ershoufang-list')):

    yield{

    'Name':div.find( 'a',class_=re.compile( 'js-title')).text,

    'Type': div.find( 'dd', class_=re.compile( 'size')).contents[ 1].text, #tag的 .contents 属性可以将tag的子节点以列表的方式输出

    'Area':div.find( 'dd',class_=re.compile( 'size')).contents[ 5].text,

    'Towards':div.find( 'dd',class_=re.compile( 'size')).contents[ 9].text,

    'Floor':div.find( 'dd',class_=re.compile( 'size')).contents[ 13].text.replace( 'n', ''),

    'Decorate':div.find( 'dd',class_=re.compile( 'size')).contents[ 17].text,

    'Address':div.find( 'span',class_=re.compile( 'area')).text.strip().replace( ' ', '').replace( 'n', ''),

    'TotalPrice':div.find( 'span',class_=re.compile( 'js-price')).text+div.find( 'span',class_=re.compile( 'yue')).text,

    'Price':div.find( 'div',class_=re.compile( 'time')).text

    }

    #有一些二手房信息缺少部分信息,如:缺少装修信息,或者缺少楼层信息,这时候需要加个判断,不然爬取就会中断。

    ifdiv[ 'Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price'] == None:

    returnNone

    exceptException:

    returnNone

    defmain():

    fori inrange( 1, 50):

    url = 'http://bj.ganji.com/fang5/o{}/'.format(i)

    content = get_one_page(url)

    print( '第{}页抓取完毕'.format(i))

    fordiv inparse_one_page(content):

    print(div)

    withopen( 'Data.csv', 'a', newline= '') asf: # Data.csv 文件存储的路径,如果默认路径就直接写文件名即可。

    fieldnames = [ 'Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price']

    writer = csv.DictWriter(f, fieldnames=fieldnames)

    writer.writeheader()

    foritem inparse_one_page(content):

    writer.writerow(item)

    time.sleep( 3) #设置爬取频率,一开始我就是爬取的太猛,导致网页需要验证。

    if__name__== '__main__':

    main()

    正则爬取:我研究了好久,还是没有解决。

    这一过程中容易遇见的问题有:

    有一些房屋缺少部分信息,如缺少装修信息,这个时候需要加一个判断,如果不加判断,爬取就会自动终止(我在这里跌了很大的坑)。

    Data.csv知识点存储文件路径默认是工作目录,关于Python中如何查看工作目录:

    importos

    #查看pyhton 的默认工作目录

    print(os.getcwd())

    #修改时工作目录

    os.chdir( 'e:workpython')

    print(os.getcwd())

    #输出工作目录

    e:workpython

    爬虫打印的是字典形式,每个房屋信息都是一个字典,由于Python中excel相关库是知识盲点,所以爬虫的时候将字典循环直接写入了CSV。

    Pycharm中打印如下:

    6479ad6ab6b54616aef62e13bf021e69.jpeg

    将字典循环直接写入CSV效果如下:

    c85d3164b2364647940b2178fceee2d4.jpeg

    很多初学者对于Address不知如何处理,这里强调一下Beautiful Soup 中.contents的用法,亲身体会,我在这里花了好多时间才找到答案。

    985a3efe0c644538a4337fbf0b6afd43.png

    R对爬取的二手房房价做一般线性回归分析

    下面我们用R对抓取的赶集网北京二手房数据做一些简单的分析。

    数据的说明

    Name:主要是商家的醒目标题,不具备分析参考意义

    Type:卧室数、客厅数、卫生间数

    Area:面积(平方米)

    Towards:朝向

    Floor:楼层

    Decorate:装修情况,如精装修、简单装修、毛坯房

    Address:二手房的地址

    TotalPrice:总价

    Price:均价(元/平方米)

    数据清洗

    data<-read.csv("E://Data For R/RData/data.csv")

    DATA<-data[,-c(1,7)] #将Name和Address两列去掉

    DATA[sample(1:nrow(DATA),size=10),]

    48c1b500282f478da37b807dc5f8c05f.png

    #在爬取的时候加入了判断,所以不知道爬取的数据中是否存在缺失值,这里检查一下

    colSums( is.na(DATA))

    #这里将Type的卧室客厅和卫生间分为三个不同的列

    ##这里需要注意,有一些房屋没有客厅如:1室1卫这时候需要单独处理,还有一些没有厕所信息。

    library(tidyr)

    library(stringr)

    DATA=separate(data=DATA,col=Type,into = c( "Bedrooms", "Halls"),sep= "室")

    DATA=separate(data=DATA,col=Halls,into = c( "Halls", "Toilet"),sep= "厅")

    ##将卫生间后面的汉字去掉

    DATA $Toilet<-str_replace(DATA $Toilet, "卫", "")

    ###如图六,将Halls中带有汉字去掉,因为有一些房屋信息没有客厅,如:1室1厅,在分成卧室和客厅时,会将卫生间分到客厅一列。

    DATA $Halls<-str_replace(DATA $Halls, "卫", "")

    ##取出没有客厅信息的数据,这些数据被separate到Halls列

    newdata<-DATA[ which(DATA $Toilet% in% NA),2]

    newdata

    ##将没有客厅的房屋信息Halls列填充为0

    DATA[ which(DATA $Toilet% in% NA),2]<-0

    DATA[ which(DATA $Toilet% in% NA),3]<-newdata

    colSums(DATA== "")

    Bedrooms Halls Toilet Area Towards Floor Decorate

    0 0 2 0 0 0 0

    TotalPrice Price

    0 0

    ##发现有2个厕所没有信息,将其填写为0。

    DATA $Toilet[DATA $Toilet== ""]<-0

    ##这里将Area后的㎡去掉

    DATA$Area<-str_replace(DATA$Area,"㎡","")

    ##查看Towards的类型

    table(DATA$Towards)

    Towards 北向 东北向 东南向 东西向 东向 南北向 南向 西北向

    51 25 23 50 65 32 1901 678 38

    西南向 西向

    28 26

    ##将Floor信息带括号的全部去除

    DATA$Floor<-str_replace(DATA$Floor,"[(].*[)]","")##正则表达式

    #查看Floor的类别信息

    低层 地下 高层 共1层 共2层 共3层 共4层 共5层 中层

    632 32 790 36 61 101 68 130 1016

    #分别将TotalPrice和Price后面的万元、元/㎡去掉

    DATA$TotalPrice<-str_replace(DATA$TotalPrice,"万元","")

    DATA$Price<-str_replace(DATA$Price,"元/㎡","")

    head(DATA)

    e0b441a2683a4881b94d2670f0c2bf28.png

    ##将数据转换格式

    DATA$Bedrooms<- as.factor(DATA$Bedrooms)

    DATA$Halls<- as.factor(DATA$Halls)

    DATA$Toilet<- as.factor(DATA$Toilet)

    DATA$Area<- as.numeric(DATA$Area)

    DATA$TotalPrice<- as.numeric(DATA$TotalPrice)

    DATA$Price<- as.numeric(DATA$Price)

    DATA$Towards<- as.factor(DATA$Towards)

    DATA$Decorate<- as.factor(DATA$Decorate)

    str(DATA)

    f6db1026405e445f90635d47e4aa1cfd.png

    以上数据清洗完毕。

    描述性分析

    这部分的主要思路是探究单个自变量对因变量的影响,对房价的影响因素进行模拟探究之前,首先对各变量进行描述性分析,以初步判断房价的影响因素。这里探究各个因素对总价影响。

    探究Bedrooms与TotalPrice的关系

    table(DATA $Bedrooms)

    1 2 3 4 5 6 7 9

    541 1225 779 193 102 20 5 1

    ##由于拥有6、7、9个卧室数的数量较少,这里我们排出这些数据。

    DATA<-DATA[-( which(DATA $Bedrooms% in% "6")),]

    DATA<-DATA[-( which(DATA $Bedrooms% in% "7")),]

    DATA<-DATA[-( which(DATA $Bedrooms% in% "9")),]

    table(DATA $Bedrooms)

    1 2 3 4 5

    541 1225 779 193 102

    library(ggplot2)

    ggplot(DATA,aes(x=Bedrooms,y=TotalPrice))+geom_boxplot(col= "red")

    30f2eaffa9cd425e9833a7b13542254f.jpeg

    DATA$Bedrooms<- as.numeric(DATA$Bedrooms)

    ##这里将卧室数为1、2、3命名为A,4为B,5为C

    DATA$Bedrooms[DATA$Bedrooms== '1']<- "A"

    DATA$Bedrooms[DATA$Bedrooms== '2']<- "A"

    DATA$Bedrooms[DATA$Bedrooms== '3']<- "A"

    DATA$Bedrooms[DATA$Bedrooms== '4']<- "B"

    DATA$Bedrooms[DATA$Bedrooms== '5']<- "C"

    不同卧室数,TotalPrice不同。且随着卧室数的增多,总价越高,符合大众的认知。

    探究Halls与TotalPrice的关系

    table(DATA $Halls)

    0 1 2 3 4 5 9

    20 1674 1050 77 18 1 0

    ##5个客厅只有一个个体,我们这里将其排出

    DATA<-DATA[-( which(DATA $Halls% in% "5")),]

    table(DATA $Halls)

    0 1 2 3 4 5 9

    20 1674 1050 77 18 0 0

    ggplot(DATA,aes(x=Halls,y=TotalPrice))+geom_boxplot(col= "red")

    64c33351ac964642a1652d70db7d4850.jpeg

    客厅数为3时候总价最高,客厅数为0、1和2的时候总价低于客厅数3和客厅数4。

    探究Toilet与TotalPrice的关系

    #探究卫生间与总价的关系

    table(DATA $Toilet)

    0 1 2 3 4 5 6 7 9

    2 2142 470 116 74 26 7 2 0

    #这里将卫生间数为0、6和7的去掉

    DATA<-DATA[-( which(DATA $Toilet% in% "0")),]

    DATA<-DATA[-( which(DATA $Toilet% in% "6")),]

    DATA<-DATA[-( which(DATA $Toilet% in% "7")),]

    table(DATA $Toilet)

    0 1 2 3 4 5 6 7 9

    0 2142 470 116 74 26 0 0 0

    ggplot(DATA,aes(x=Toilet,y=TotalPrice))+geom_boxplot(col= "red")

    aad5a776327c40559936b20601dcd6c6.jpeg

    一般卧室数越多,卫生间数也越多,即卫生间数越多,总价越高。

    探究Area与TotalPrice的关系

    ggplot(DATA, aes(x=Area, y=TotalPrice)) + geom_point(col= 'red')

    d92c5a56cc2f44d58fb593d63ce3f72d.jpeg

    这个完全符合住房面积越大,总价越高。

    探究Towards与TotalPrice的关系

    ggplot(DATA,aes(x=Towards,y=TotalPrice))+geom_boxplot(col= "red")

    afea4bc4dee84cb68af90a9183ae49d8.jpeg

    探究Floor与TotalPrice的关系

    ggplot(DATA,aes(x=Floor,y=TotalPrice))+geom_boxplot(col= "red")

    571d10e8b1ea4e0a929eb35b3454573f.jpeg

    图中信息显示楼层一共只有1、2、3、地下的总价较高。

    探究Decorate与TotalPrice的关系

    ggplot(DATA,aes(x=Decorate,y=TotalPrice))+geom_boxplot(col= "red")

    c19f050aab5947ed81302231bc9444a1.jpeg

    不同装修信息对总价影响较小。

    模型建立

    fit <-lm(TotalPrice~Bedrooms+Halls+Toilet+Area+Towards+Floor+Decorate,data=DATA)

    summary(fit)

    Call:

    lm(formula = TotalPrice ~ Bedrooms + Halls + Toilet + Area +

    Towards + Floor + Decorate, data = DATA)

    Residuals:

    Min 1Q Median 3Q Max

    -1330.80-103.49-21.4163.882961.59

    Coefficients:

    Estimate Std. Errort value Pr(>|t|)

    (Intercept) -112.763388.3010-1.2770.201697

    Bedrooms2 -43.593416.2533-2.6820.007359**

    Bedrooms3 -82.656520.7641-3.9817.04e-05***

    Bedrooms4 -63.309634.9521-1.8110.070198.

    Bedrooms5 79.061854.07631.4620.143842

    Halls1 -5.066364.2764-0.0790.937182

    Halls2 -53.890565.4427-0.8230.410307

    Halls3 -303.975079.2280-3.8370.000127***

    Halls4 -528.5427104.0849-5.0784.07e-07***

    Toilet2 112.956619.11715.9093.87e-09***

    Toilet3 543.730438.805614.012< 2e-16***

    Toilet4 735.189455.097713.343< 2e-16***

    Toilet5 338.790684.28514.0205.98e-05***

    Area 5.10910.161931.557< 2e-16***

    Towards东北向 138.908879.38171.7500.080248.

    Towards东南向 187.189568.53882.7310.006351**

    Towards东西向 176.305565.83842.6780.007453**

    Towards东向 210.943573.27442.8790.004022**

    Towards南北向 75.783157.11991.3270.184704

    Towards南向 60.194956.96781.0570.290763

    Towards西北向 75.432671.14151.0600.289091

    Towards西南向 169.810675.96262.2350.025467*

    Towards西向 234.081676.55853.0580.002253**

    Floor地下 -812.357863.3277-12.828< 2e-16***

    Floor高层 12.352514.24660.8670.385991

    Floor共 1层 -313.727852.1342-6.0182.00e-09***

    Floor共 2层 -453.369241.6829-10.877< 2e-16***

    Floor共 3层 -601.703244.3336-13.572< 2e-16***

    Floor共 4层 -183.786636.3396-5.0574.52e-07***

    Floor共 5层 -41.418425.7922-1.6060.108419

    Floor中层 -1.722313.5961-0.1270.899204

    Decorate简单装修 -63.159122.0584-2.8630.004224**

    Decorate精装修 -49.327619.8544-2.4840.013033*

    Decorate毛坯 -157.029924.3012-6.4621.22e-10***

    ---

    Signif. codes: 0‘***’ 0.001‘**’ 0.01‘*’ 0.05‘.’ 0.1‘ ’ 1

    Residual standard error: 265.5on2794degrees offreedom

    Multiple R-squared: 0.6852, Adjusted R-squared: 0.6815

    F-statistic: 184.3on33and2794DF, p-value: < 2.2e-16

    模型的F检验拒绝原假设,说明建立的模型是显著的;Ajusted R-squared为0.6815,模型的拟合程度尚可接受。

    作者:徐涛,19年应届毕业生,专注于珊瑚礁研究,喜欢用R各种清洗数据,知乎用户@parkson。

    声明:本文为公众号数据森麟投稿,版权归对方所有。

    责任编辑:

    展开全文
  • 本文主要分为两部分:Python爬取赶集网北京二手房数据,R对爬取的二手房房价做线性回归分析,适合刚刚接触Python&R的同学们学习参考。 01 Python爬取赶集网北京二手房数据 入门爬虫一个月,所以对每一个网站都...

    房价高是北漂们一直关心的话题,本文就对北京的二手房数据进行了分析。

    本文主要分为两部分:Python爬取赶集网北京二手房数据,R对爬取的二手房房价做线性回归分析,适合刚刚接触Python&R的同学们学习参考。

    01

    Python爬取赶集网北京二手房数据

    入门爬虫一个月,所以对每一个网站都使用了Xpath、Beautiful Soup、正则三种方法分别爬取,用于练习巩固。数据来源如下:

    1ecd8fe79a51e8fdddd855f4f6bb7d3777bda911

    Xpath爬取:

    这里主要解决运用Xpath如何判断某些元素是否存在的问题,比如如果房屋没有装修信息,不加上判断,某些元素不存在就会导致爬取中断。

    
    
    import requests
    from lxml import etree
    from requests.exceptions import RequestException
    import multiprocessing
    import time

    headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

    def get_one_page(url):
    try:
    response = requests.get(url, headers=headers)
    if response.status_code == 200:
    return response.text
    return None
    except RequestException:
    return None

    def parse_one_page(content):
    try:
    selector = etree.HTML(content)
    ALL = selector.xpath('//*[@id="f_mew_list"]/div[6]/div[1]/div[3]/div[1]/div')
    for div in ALL:
    yield {
    'Name': div.xpath('dl/dd[1]/a/text()')[0],
    'Type': div.xpath('dl/dd[2]/span[1]/text()')[0],
    'Area': div.xpath('dl/dd[2]/span[3]/text()')[0],
    'Towards': div.xpath('dl/dd[2]/span[5]/text()')[0],
    'Floor': div.xpath('dl/dd[2]/span[7]/text()')[0].strip().replace('\n', ""),
    'Decorate': div.xpath('dl/dd[2]/span[9]/text()')[0],
    #地址需要特殊处理一下
    'Address': div.xpath('dl/dd[3]//text()')[1]+div.xpath('dl/dd[3]//text()')[3].replace('\n','')+div.xpath('dl/dd[3]//text()')[4].strip(),
    'TotalPrice': div.xpath('dl/dd[5]/div[1]/span[1]/text()')[0] + div.xpath('dl/dd[5]/div[1]/span[2]/text()')[0],
    'Price': div.xpath('dl/dd[5]/div[2]/text()')[0]
    }
    if div['Name','Type','Area','Towards','Floor','Decorate','Address','TotalPrice','Price'] == None:##这里加上判断,如果其中一个元素为空,则输出None
    return None
    except Exception:
    return None

    def main():
    for i in range(1, 500):#这里设置爬取500页数据,在数据范围内,大家可以自设置爬取的量
    url = 'http://bj.ganji.com/fang5/o{}/'.format(i)
    content = get_one_page(url)
    print('第{}页抓取完毕'.format(i))
    for div in parse_one_page(content):
    print(div)

    if __name__ == '__main__':
    main()

    Beautiful Soup爬取:

    
    
    import requests
    import re
    from requests.exceptions import RequestException
    from bs4 import BeautifulSoup
    import csv
    import time

    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}

    def get_one_page(url):
    try:
    response = requests.get(url,headers = headers)
    if response.status_code == 200:
    return response.text
    return None
    except RequestException:
    return None

    def parse_one_page(content):
    try:
    soup = BeautifulSoup(content,'html.parser')
    items = soup.find('div',class_=re.compile('js-tips-list'))
    for div in items.find_all('div',class_=re.compile('ershoufang-list')):
    yield {
    'Name':div.find('a',class_=re.compile('js-title')).text,
    'Type': div.find('dd', class_=re.compile('size')).contents[1].text,#tag的 .contents 属性可以将tag的子节点以列表的方式输出
    'Area':div.find('dd',class_=re.compile('size')).contents[5].text,
    'Towards':div.find('dd',class_=re.compile('size')).contents[9].text,
    'Floor':div.find('dd',class_=re.compile('size')).contents[13].text.replace('\n',''),
    'Decorate':div.find('dd',class_=re.compile('size')).contents[17].text,
    'Address':div.find('span',class_=re.compile('area')).text.strip().replace(' ','').replace('\n',''),
    'TotalPrice':div.find('span',class_=re.compile('js-price')).text+div.find('span',class_=re.compile('yue')).text,
    'Price':div.find('div',class_=re.compile('time')).text
    }
    #有一些二手房信息缺少部分信息,如:缺少装修信息,或者缺少楼层信息,这时候需要加个判断,不然爬取就会中断。
    if div['Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price'] == None:
    return None
    except Exception:
    return None

    def main():
    for i in range(1,50):
    url = 'http://bj.ganji.com/fang5/o{}/'.format(i)
    content = get_one_page(url)
    print('第{}页抓取完毕'.format(i))
    for div in parse_one_page(content):
    print(div)
    with open('Data.csv', 'a', newline='') as f: # Data.csv 文件存储的路径,如果默认路径就直接写文件名即可。
    fieldnames = ['Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price']
    writer = csv.DictWriter(f, fieldnames=fieldnames)
    writer.writeheader()
    for item in parse_one_page(content):
    writer.writerow(item)
    time.sleep(3)#设置爬取频率,一开始我就是爬取的太猛,导致网页需要验证。

    if __name__=='__main__':
    main()

    正则爬取:我研究了好久,还是没有解决。

    这一过程中容易遇见的问题有:

    • 有一些房屋缺少部分信息,如缺少装修信息,这个时候需要加一个判断,如果不加判断,爬取就会自动终止(我在这里跌了很大的坑)。
    • Data.csv知识点存储文件路径默认是工作目录,关于Python中如何查看工作目录:
    
    
    import os

    #查看pyhton 的默认工作目录
    print(os.getcwd())

    #修改时工作目录
    os.chdir('e:\\workpython')
    print(os.getcwd())
    #输出工作目录
    e:\workpython
    • 爬虫打印的是字典形式,每个房屋信息都是一个字典,由于Python中excel相关库是知识盲点,所以爬虫的时候将字典循环直接写入了CSV。

    Pycharm中打印如下:

    640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

    将字典循环直接写入CSV效果如下:

    9beb969e27e01b008a6e462b229c373f71673f82

    • 很多初学者对于Address不知如何处理,这里强调一下Beautiful Soup 中.contents的用法,亲身体会,我在这里花了好多时间才找到答案。

    b5e43138d5d6a693cb3cac9e66ead3bf95aba343

    02

    R对爬取的二手房房价做一般线性回归分析

    下面我们用R对抓取的赶集网北京二手房数据做一些简单的分析。

    数据的说明

    Name:主要是商家的醒目标题,不具备分析参考意义

    Type:卧室数、客厅数、卫生间数

    Area:面积(平方米)

    Towards:朝向

    Floor:楼层

    Decorate:装修情况,如精装修、简单装修、毛坯房

    Address:二手房的地址

    TotalPrice:总价

    Price:均价(元/平方米)

    数据清洗

    
    
    data<-read.csv("E://Data For R/RData/data.csv")
    DATA<-data[,-c(1,7)]#将Name和Address两列去掉
    DATA[sample(1:nrow(DATA),size=10),]

    1f5b6ad9e1c055746f267760c785a08fa105d8b6

    
    
    #在爬取的时候加入了判断,所以不知道爬取的数据中是否存在缺失值,这里检查一下
    colSums(is.na(DATA))
    
    
    #这里将Type的卧室客厅和卫生间分为三个不同的列
    ##这里需要注意,有一些房屋没有客厅如:1室1卫这时候需要单独处理,还有一些没有厕所信息。
    library(tidyr)
    library(stringr)
    DATA=separate(data=DATA,col=Type,into = c("Bedrooms","Halls"),sep="室")
    DATA=separate(data=DATA,col=Halls,into = c("Halls","Toilet"),sep="厅")
    ##将卫生间后面的汉字去掉
    DATA$Toilet<-str_replace(DATA$Toilet,"卫","")
    ###如图六,将Halls中带有汉字去掉,因为有一些房屋信息没有客厅,如:1室1厅,在分成卧室和客厅时,会将卫生间分到客厅一列。
    DATA$Halls<-str_replace(DATA$Halls,"卫","")
    ##取出没有客厅信息的数据,这些数据被separate到Halls列
    newdata<-DATA[which(DATA$Toilet %in% NA),2]
    newdata
    ##将没有客厅的房屋信息Halls列填充为0
    DATA[which(DATA$Toilet %in% NA),2]<-0
    DATA[which(DATA$Toilet %in% NA),3]<-newdata
    colSums(DATA=="")
    Bedrooms Halls Toilet Area Towards Floor Decorate
    0 0 2 0 0 0 0
    TotalPrice Price
    0 0

    ##发现有2个厕所没有信息,将其填写为0。
    DATA$Toilet[DATA$Toilet == ""]<-0

    85575d50ca79e7df3a84e54f8f071fab4671beb1

    
    
    ##这里将Area后的㎡去掉
    DATA$Area<-str_replace(DATA$Area,"㎡","")

    ##查看Towards的类型
    table(DATA$Towards)

    Towards 北向 东北向 东南向 东西向 东向 南北向 南向 西北向
    51 25 23 50 65 32 1901 678 38
    西南向 西向
    28 26
    ##将Floor信息带括号的全部去除
    DATA$Floor<-str_replace(DATA$Floor,"[(].*[)]","")##正则表达式
    #查看Floor的类别信息
    低层 地下 高层 共1层 共2层 共3层 共4层 共5层 中层
    632 32 790 36 61 101 68 130 1016

    #分别将TotalPrice和Price后面的万元、元/㎡去掉

    DATA$TotalPrice<-str_replace(DATA$TotalPrice,"万元","")
    DATA$Price<-str_replace(DATA$Price,"元/㎡","")

    head(DATA)

    0b6ba6641f2ac493f5f2496dcca61dae33930925

    
    
    ##将数据转换格式
    DATA$Bedrooms<-as.factor(DATA$Bedrooms)
    DATA$Halls<-as.factor(DATA$Halls)
    DATA$Toilet<-as.factor(DATA$Toilet)
    DATA$Area<-as.numeric(DATA$Area)
    DATA$TotalPrice<-as.numeric(DATA$TotalPrice)
    DATA$Price<-as.numeric(DATA$Price)
    DATA$Towards<-as.factor(DATA$Towards)
    DATA$Decorate<-as.factor(DATA$Decorate)
    str(DATA)

    963d3f2e8456ba276324344618e9225cc3eaf7e3

    以上数据清洗完毕。

    03

    描述性分析

    这部分的主要思路是探究单个自变量对因变量的影响,对房价的影响因素进行模拟探究之前,首先对各变量进行描述性分析,以初步判断房价的影响因素。这里探究各个因素对总价影响。

    探究Bedrooms与TotalPrice的关系

    
    
    table(DATA$Bedrooms)
    1 2 3 4 5 6 7 9
    541 1225 779 193 102 20 5 1
    ##由于拥有6、7、9个卧室数的数量较少,这里我们排出这些数据。
    DATA<-DATA[-(which(DATA$Bedrooms %in% "6")),]
    DATA<-DATA[-(which(DATA$Bedrooms %in% "7")),]
    DATA<-DATA[-(which(DATA$Bedrooms %in% "9")),]
    table(DATA$Bedrooms)
    1 2 3 4 5
    541 1225 779 193 102

    library(ggplot2)
    ggplot(DATA,aes(x=Bedrooms,y=TotalPrice))+geom_boxplot(col="red")

    43f69655cf52d007ebfdd55c6432637cf742f69c
    
    
    DATA$Bedrooms<-as.numeric(DATA$Bedrooms)
    ##这里将卧室数为1、2、3命名为A,4为B,5为C
    DATA$Bedrooms[DATA$Bedrooms=='1']<-"A"
    DATA$Bedrooms[DATA$Bedrooms=='2']<-"A"
    DATA$Bedrooms[DATA$Bedrooms=='3']<-"A"
    DATA$Bedrooms[DATA$Bedrooms=='4']<-"B"
    DATA$Bedrooms[DATA$Bedrooms=='5']<-"C"

    不同卧室数,TotalPrice不同。且随着卧室数的增多,总价越高,符合大众的认知。

    探究Halls与TotalPrice的关系

    
    
    table(DATA$Halls)
    0 1 2 3 4 5 9
    20 1674 1050 77 18 1 0
    ##5个客厅只有一个个体,我们这里将其排出
    DATA<-DATA[-(which(DATA$Halls %in% "5")),]
    table(DATA$Halls)
    0 1 2 3 4 5 9
    20 1674 1050 77 18 0 0
    ggplot(DATA,aes(x=Halls,y=TotalPrice))+geom_boxplot(col="red")

    9ccbf39777510dc925be108542b304833f6d0d6a

    客厅数为3时候总价最高,客厅数为0、1和2的时候总价低于客厅数3和客厅数4。

    探究Toilet与TotalPrice的关系

    
    
    #探究卫生间与总价的关系
    table(DATA$Toilet)
    0 1 2 3 4 5 6 7 9
    2 2142 470 116 74 26 7 2 0
    #这里将卫生间数为0、6和7的去掉
    DATA<-DATA[-(which(DATA$Toilet %in% "0")),]
    DATA<-DATA[-(which(DATA$Toilet %in% "6")),]
    DATA<-DATA[-(which(DATA$Toilet %in% "7")),]
    table(DATA$Toilet)
    0 1 2 3 4 5 6 7 9
    0 2142 470 116 74 26 0 0 0
    ggplot(DATA,aes(x=Toilet,y=TotalPrice))+geom_boxplot(col="red")

    049557fd4b057a7363b30ec997ebf2571ec1aac3

    一般卧室数越多,卫生间数也越多,即卫生间数越多,总价越高。

    探究Area与TotalPrice的关系

    ggplot(DATA, aes(x=Area, y=TotalPrice)) + geom_point(col='red')

    fd6b64ef3a6393c25bd6eb1df438730db0b487d6

    这个完全符合住房面积越大,总价越高。

    探究Towards与TotalPrice的关系

    ggplot(DATA,aes(x=Towards,y=TotalPrice))+geom_boxplot(col="red")
    6927f253ad2cc154b3674056f158bc8835546316

    探究Floor与TotalPrice的关系

    ggplot(DATA,aes(x=Floor,y=TotalPrice))+geom_boxplot(col="red")
    b8a3eb426697ac1131c3a434d55513d0104a1ae9

    图中信息显示楼层一共只有1、2、3、地下的总价较高。

    探究Decorate与TotalPrice的关系

    ggplot(DATA,aes(x=Decorate,y=TotalPrice))+geom_boxplot(col="red")
    840b8ecee1777425957da20414bc23bd39a46ab9

    不同装修信息对总价影响较小。

    04

    模型建立


    
    
    fit <-lm(TotalPrice~Bedrooms+Halls+Toilet+Area+Towards+Floor+Decorate,data=DATA)
    summary(fit)

    Call:
    lm(formula = TotalPrice ~ Bedrooms + Halls + Toilet + Area +
    Towards + Floor + Decorate, data = DATA)

    Residuals:
    Min 1Q Median 3Q Max
    -1330.80 -103.49 -21.41 63.88 2961.59

    Coefficients:
    Estimate Std. Error t value Pr(>|t|)
    (Intercept) -112.7633 88.3010 -1.277 0.201697
    Bedrooms2 -43.5934 16.2533 -2.682 0.007359 **
    Bedrooms3 -82.6565 20.7641 -3.981 7.04e-05 ***
    Bedrooms4 -63.3096 34.9521 -1.811 0.070198 .
    Bedrooms5 79.0618 54.0763 1.462 0.143842
    Halls1 -5.0663 64.2764 -0.079 0.937182
    Halls2 -53.8905 65.4427 -0.823 0.410307
    Halls3 -303.9750 79.2280 -3.837 0.000127 ***
    Halls4 -528.5427 104.0849 -5.078 4.07e-07 ***
    Toilet2 112.9566 19.1171 5.909 3.87e-09 ***
    Toilet3 543.7304 38.8056 14.012 < 2e-16 ***
    Toilet4 735.1894 55.0977 13.343 < 2e-16 ***
    Toilet5 338.7906 84.2851 4.020 5.98e-05 ***
    Area 5.1091 0.1619 31.557 < 2e-16 ***
    Towards东北向 138.9088 79.3817 1.750 0.080248 .
    Towards东南向 187.1895 68.5388 2.731 0.006351 **
    Towards东西向 176.3055 65.8384 2.678 0.007453 **
    Towards东向 210.9435 73.2744 2.879 0.004022 **
    Towards南北向 75.7831 57.1199 1.327 0.184704
    Towards南向 60.1949 56.9678 1.057 0.290763
    Towards西北向 75.4326 71.1415 1.060 0.289091
    Towards西南向 169.8106 75.9626 2.235 0.025467 *
    Towards西向 234.0816 76.5585 3.058 0.002253 **
    Floor地下 -812.3578 63.3277 -12.828 < 2e-16 ***
    Floor高层 12.3525 14.2466 0.867 0.385991
    Floor共1-313.7278 52.1342 -6.018 2.00e-09 ***
    Floor共2-453.3692 41.6829 -10.877 < 2e-16 ***
    Floor共3-601.7032 44.3336 -13.572 < 2e-16 ***
    Floor共4-183.7866 36.3396 -5.057 4.52e-07 ***
    Floor共5-41.4184 25.7922 -1.606 0.108419
    Floor中层 -1.7223 13.5961 -0.127 0.899204
    Decorate简单装修 -63.1591 22.0584 -2.863 0.004224 **
    Decorate精装修 -49.3276 19.8544 -2.484 0.013033 *
    Decorate毛坯 -157.0299 24.3012 -6.462 1.22e-10 ***
    ---
    Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

    Residual standard error: 265.5 on 2794 degrees of freedom
    Multiple R-squared: 0.6852, Adjusted R-squared: 0.6815
    F-statistic: 184.3 on 33 and 2794 DF, p-value: < 2.2e-16

    模型的F检验拒绝原假设,说明建立的模型是显著的;Ajusted R-squared为0.6815,模型的拟合程度尚可接受。


    原文发布时间为:2018-08-21

    本文作者:徐涛

    本文来自云栖社区合作伙伴“CDA数据分析师”,了解相关信息可以关注“CDA数据分析师”。

    展开全文
  • Python爬取赶集网北京二手房数据 入门爬虫一个月,所以对每一个网站都使用了Xpath、Beautiful Soup、正则三种方法分别爬取,用于练习巩固。数据来源如下: Xpath爬取: 这里主要解决运用Xpath如何判断某些元素是否...

    Python爬取赶集网北京二手房数据

    入门爬虫一个月,所以对每一个网站都使用了Xpath、Beautiful Soup、正则三种方法分别爬取,用于练习巩固。数据来源如下:
    在这里插入图片描述
    Xpath爬取:

    这里主要解决运用Xpath如何判断某些元素是否存在的问题,比如如果房屋没有装修信息,不加上判断,某些元素不存在就会导致爬取中断。

    import requests
    from lxml import etree
    from requests.exceptions import RequestException
    import multiprocessing
    import time
    '''
    更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
    '''
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
    
    def get_one_page(url):
        try:
            response = requests.get(url, headers=headers)
            if response.status_code == 200:
                return response.text
            return None
        except RequestException:
            return None
    
    def parse_one_page(content):
        try:
            selector = etree.HTML(content)
            ALL = selector.xpath('//*[@id="f_mew_list"]/div[6]/div[1]/div[3]/div[1]/div')
            for div in ALL:
                yield {
                    'Name': div.xpath('dl/dd[1]/a/text()')[0],
                    'Type': div.xpath('dl/dd[2]/span[1]/text()')[0],
                    'Area': div.xpath('dl/dd[2]/span[3]/text()')[0],
                    'Towards': div.xpath('dl/dd[2]/span[5]/text()')[0],
                    'Floor': div.xpath('dl/dd[2]/span[7]/text()')[0].strip().replace('\n', ""),
                    'Decorate': div.xpath('dl/dd[2]/span[9]/text()')[0],
                    #地址需要特殊处理一下
                    'Address': div.xpath('dl/dd[3]//text()')[1]+div.xpath('dl/dd[3]//text()')[3].replace('\n','')+div.xpath('dl/dd[3]//text()')[4].strip(),
                    'TotalPrice': div.xpath('dl/dd[5]/div[1]/span[1]/text()')[0] + div.xpath('dl/dd[5]/div[1]/span[2]/text()')[0],
                    'Price': div.xpath('dl/dd[5]/div[2]/text()')[0]
                }
            if div['Name','Type','Area','Towards','Floor','Decorate','Address','TotalPrice','Price'] == None:##这里加上判断,如果其中一个元素为空,则输出None
                return None
        except Exception:
            return None
    
    def main():
        for i in range(1, 500):#这里设置爬取500页数据,在数据范围内,大家可以自设置爬取的量
            url = 'http://bj.ganji.com/fang5/o{}/'.format(i)
            content = get_one_page(url)
            print('第{}页抓取完毕'.format(i))
            for div in parse_one_page(content):
                print(div)
    
    if __name__ == '__main__':
        main()
    

    Beautiful Soup爬取:

    import requests
    import re
    from requests.exceptions import RequestException
    from bs4 import BeautifulSoup
    import csv
    import time
    
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
    
    def get_one_page(url):
        try:
            response = requests.get(url,headers = headers)
            if response.status_code == 200:
                return response.text
            return None
        except RequestException:
            return None
    
    def parse_one_page(content):
        try:
            soup = BeautifulSoup(content,'html.parser')
            items = soup.find('div',class_=re.compile('js-tips-list'))
            for div in items.find_all('div',class_=re.compile('ershoufang-list')):
                yield {
                    'Name':div.find('a',class_=re.compile('js-title')).text,
                    'Type': div.find('dd', class_=re.compile('size')).contents[1].text,#tag的 .contents 属性可以将tag的子节点以列表的方式输出
                    'Area':div.find('dd',class_=re.compile('size')).contents[5].text,
                    'Towards':div.find('dd',class_=re.compile('size')).contents[9].text,
                    'Floor':div.find('dd',class_=re.compile('size')).contents[13].text.replace('\n',''),
                    'Decorate':div.find('dd',class_=re.compile('size')).contents[17].text,
                    'Address':div.find('span',class_=re.compile('area')).text.strip().replace(' ','').replace('\n',''),
                    'TotalPrice':div.find('span',class_=re.compile('js-price')).text+div.find('span',class_=re.compile('yue')).text,
                    'Price':div.find('div',class_=re.compile('time')).text
                }
            #有一些二手房信息缺少部分信息,如:缺少装修信息,或者缺少楼层信息,这时候需要加个判断,不然爬取就会中断。
            if div['Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price'] == None:
                    return None
        except Exception:
            return None
    
    def main():
        for i in range(1,50):
            url = 'http://bj.ganji.com/fang5/o{}/'.format(i)
            content = get_one_page(url)
            print('第{}页抓取完毕'.format(i))
            for div in parse_one_page(content):
                print(div)
            with open('Data.csv', 'a', newline='') as f:  # Data.csv 文件存储的路径,如果默认路径就直接写文件名即可。
                fieldnames = ['Name', 'Type', 'Area', 'Towards', 'Floor', 'Decorate', 'Address', 'TotalPrice', 'Price']
                writer = csv.DictWriter(f, fieldnames=fieldnames)
                writer.writeheader()
                for item in parse_one_page(content):
                    writer.writerow(item)
            time.sleep(3)#设置爬取频率,一开始我就是爬取的太猛,导致网页需要验证。
    
    if __name__=='__main__':
        main()
    

    正则爬取:我研究了好久,还是没有解决。

    这一过程中容易遇见的问题有:

    • 有一些房屋缺少部分信息,如缺少装修信息,这个时候需要加一个判断,如果不加判断,爬取就会自动终止(我在这里跌了很大的坑)。
    • Data.csv知识点存储文件路径默认是工作目录,关于Python中如何查看工作目录:
    import os 
    '''
    更多Python学习资料以及源码教程资料,可以在群1136201545免费获取
    '''
    #查看pyhton 的默认工作目录
    print(os.getcwd())
    
    #修改时工作目录
    os.chdir('e:\\workpython')
    print(os.getcwd())
    #输出工作目录
    e:\workpython
    

    爬虫打印的是字典形式,每个房屋信息都是一个字典,由于Python中excel相关库是知识盲点,所以爬虫的时候将字典循环直接写入了CSV。

    Pycharm中打印如下:
    在这里插入图片描述
    将字典循环直接写入CSV效果如下:
    在这里插入图片描述
    太贵了~~~~

    展开全文
  • 近期,有个朋友联系我,想统计一下北京二手房的相关的数据,而自己用Excel统计工作量太过于繁杂,问我用Python该如何实现。 构造要访问的URL 这里,我试着抓取北京海淀区二手房的相关数据。首先,是观察一下URL的...
  • 来源:CSDN本文约3500字,建议阅读9分钟。本文根据Python爬取了赶集网北京二手房数据,R对爬取的二手房房价做线性回归分析,适合刚刚接触Python&amp;R的...
  • 爬取北京链家二手房数据

    千次阅读 2020-01-08 17:57:07
    利用python爬取北京链家主页的二手房数据爬取时间为2020年1月8日。由于链家只显示了100页、每页30条,因此只能爬取3000条数据。 后续将爬取各区的小区名,对每个小区的在售二手房数据进行收集,这样能获得更多...
  • 下面小编就为大家带来一篇python爬取安居客二手房网站数据(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 本文代码在网友pythoner111爬虫项目–爬取安居客二手房信息的基础上修改,爬取过程顺利,若有不足之处还请大家指出修改。 import requests import bs4 import time import random import pandas as pd import ...
  • 有个朋友联系我,想统计一下北京二手房的相关的数据,而自己用Excel统计工作量太过于繁杂,问我用Python该如何实现。 构造要访问的URL 这里,我试着抓取北京海淀区二手房的相关数据。首先,是观察一下URL的结构,...
  • 一篇文章详细告诉你爬虫的基本思路,并用Python实现了爬取链家海淀区二手房的信息。
  • 由于是初次使用Java写爬虫,所以代码有些繁琐,请大家见谅,并能给与指正首先分析链家北京二手房页面,使用360浏览器的审查元素功能,查看源代码,获取查询标签如图一级查询所示,此图标签所获取的是链家北京二手房...
  • python爬取链家二手房楼盘数据信息

    千次阅读 2019-05-29 16:43:48
    想看下最近房价是否能入手,抓取链家二手房、新房的信息,发现广州有些精装修88平米的3房2厅首付只要29万!平均1.1万/平: 查看请求信息 本次用的是火狐浏览器32.0配合firebug和httpfox使用,基于python3环境,...
  • 用scrapy写了个爬虫,爬取麦田北京二手房信息,一共爬取了11718条,也遇到了一些问题 页数限制 访问北京市二手房只显示100页的数据, 各地区售房数量 index_id district count 1 朝阳 6139 2 海淀 1822...
  • 今天我们主要对链家二手房数据爬取,看下我们目前的资金能买那一套。链家二手房网站:https://bj.lianjia.com/ershoufang/ 我们相对如上图所示的数据爬取,也就是两个数据,接下来开始分析 点击f12进入...
  • 目标:爬取安居客网站上前10页北京二手房数据,包括二手房源的名称、价格、几室几厅、大小、建造年份、联系人、地址、标签等。 网址为:https://beijing.anjuke.com/sale/ BeautifulSoup官网:...
  • 本文转载自数据森麟(ID:shujusenlin) 作者介绍:徐涛,19年应届毕业生,专注于珊瑚礁研究,喜欢用R各种清洗数据。...前言:本文主要分为两部分:Python爬取赶集网北京二手房数据&amp;R对爬取的二手房房价做...
  • python爬取链家网租房信息,保存到本地文件,根据自己的情况可以查找适合自己的房源
  • 爬取链家二手房信息

    2019-07-20 11:47:24
    由于爬取到的数据是保存到MySQL数据库中,所以需先在MySQL中创建数据库和表 数据库创建 # 创建数据库 create database lianjiadb charset=utf8; 进入数据库 # 进入创建的数据库 use lianjiadb; 创建表 # ...
  • python爬虫爬取链家二手房信息

    万次阅读 热门讨论 2017-05-20 15:43:06
    我代码里只爬取了3000套二手房价格,北京市实际在售的二手房大概有两万套,不是我不想全爬,只是链家只展示100页(3000套)的内容,排序方式我也并不清楚。我尝试通过分区域来爬取以获得更多的数据,但爬虫更容易被...
  • 目标是北京二手房信息,下面开始分析。网页结构分析采用安居客网页信息作为二手房的信息来源,直接点击进入二手房信息的页面。每页的住房信息:点开链接后的详细信息:博主并没有采用分区域进行爬取,博主是直接进行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 670
精华内容 268
关键字:

爬取北京二手房数据