爬虫实战——绝对通俗易懂,爬取房产数据

爬虫介绍

简单介绍一下爬虫,百度百科“网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。”

在我们这次的实战项目中,你需要了解的库有urllib,re,BeautifulSoup, request

实战目标

不说废话,直接说一下,本次爬虫实战的任务目标,就是爬取房产网站上的房产的价格,位置,房屋面积,装修情况等等网站上显示的信息。

这里以向租网举例,首先我们点到你想要爬取的网站页面,比如我们想知道黄浦区的所有写字楼的名称、面积和他的价格及其他信息,我们点到这个页面,红框里的就是我们想要获取的信息。
在这里插入图片描述
可以看一下,黄浦区的大厦一共有85页,我们的目标就是把这85内的每个楼盘的详细信息整理下来。
在这里插入图片描述

1.获取url

第一步我们首先要获取我们要抓取网站的url,翻到浏览器的网站
在这里插入图片描述
就可以看到网站的url了,这里我们看到page=85,整好所有的信息就只有85页,所以要获得每一个页面的url只需要改变等号后面的值就可以了。

接着,用request读取一下html的具体内容,不过在这之前,有一个点需要注意,作为企业肯定不想让你轻易地获得他的信息,有的企业有专门的防爬措施,那么如果要向去进行一个爬虫设计,第一就是要给自己做一个身份卡,让我们这个程序可以访问该网站的资源,最简单的措施就是让我们这个给我们这个软件的身份卡浏览器的身份,作为浏览器访问企业的资源是没有问题的。

利用google开发者模式,打开我们的目标网址向租网,按F12打开开发者模式,点击network后再点击左侧任意一个项目,接着在右侧的窗口上找到该浏览器访问目标网址的身份信息 Request Headers。
在这里插入图片描述
在该标题的子项目中找到user-agent,这个就是你访问该网站的实体对象,一般来说,用这个身份信息就足够了。
在这里插入图片描述
接着,用这个身份信息去获得该网页的html,代码如下所示。

import urllib
import re
from bs4 import BeautifulSoup
import pandas as pd

url = 'https://www.xiangzuwang.cn/xiezilou/sx/a803?page=1'
head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
request = urllib.request.Request(url, headers = head)
response = urllib.request.urlopen(request)
html = response.read().decode('utf-8')

2.利用BeautifulSoup获取html的索引

Beautiful Soup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。 Beautiful Soup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup 就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。 Beautiful Soup 已成为和 lxml、html6lib 一样出色的 python 解释器,为用户灵活地提供不同的解析策略或强劲的速度。

上文获得了该网站的html后,利用BeautifulSoup来解析该html文档。

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

这样我们就获得了一个BeautifulSoup的树模型,可以方便的查询所需要的数据了。

3.查找所需数据索引

这里我们回到我们的目标网站,F12打开开发者模式下的elements左边的小箭头来快速获得我们需要的信息的索引。
在这里插入图片描述
点完小箭头后点到网站所要获取的信息的具体内容处,在这里点到所在楼盘位置,他所在的html位置是div class=“address”,我们就利用这个索引获得其信息。
在这里插入图片描述
获取完索引信息后,用BeautifulSoup的find_all函数来定位到我们所要的信息。

soup.find_all('div', class_ = 'address')

这时候就返回了一个列表,观察列表中每三个元素是一个大厦的,这是因为在html里面,这三个元素的html索引地址是一样的,稍作处理让每一个元素就代表一个样本。
在这里插入图片描述

each = []
for i in range(int(len(soup.find_all('div', class_ = 'address'))/3)):
    str1 = str(soup.find_all('div', class_ = 'address')[3*i])
    str2 = str(soup.find_all('div', class_ = 'address')[3*i+1])
    str3 = str(soup.find_all('div', class_ = 'address')[3*i+2])
    each.append(str1+str2+str3)
each

在这里插入图片描述
这样就获得了一个元素代表一个样本的所有信息。

4.正则表达式获取所需要的信息

正则表达式的基本信息可以参考官方文档,在这里如果我们要获得大厦名字,我们给正则表达式制定好筛选
在这里插入图片描述

findlocation = re.compile(r' target="_blank">(.*?)<')
re.findall(findlocation, each[0])
# ['兰生大厦', '黄浦', '淮海中路']

在写一个循环把他加到列表里就完成了。

buildings = []
district = []
areas = []

for i in each:
    buildings.append(re.findall(findlocation, i)[0])
    district.append(re.findall(findlocation, i)[1])
    areas.append(re.findall(findlocation, i)[2])
buildings

这样我们就完成了大厦名称的爬取,同理你可以获得街道,价格和面积及其他信息。注意这里只是简单一页的爬取,这个网页一共有85页,需要经过85页的循环获得全部数据。

最后,利用pands转化成数据框或者写入sql或者保存成你想要的格式就好了。

完整代码

# -*- coding: utf-8 -*-
import urllib
import re
from bs4 import BeautifulSoup
import pandas as pd

baseurl = 'https://www.xiangzuwang.cn/xiezilou/sx/a803?page='



buildings = []
decoration = []
district = []
domain = []
areas = []
streets = []


findlocation = re.compile(r' target="_blank">(.*?)<')
finddomain = re.compile(r'面积:(.*?)m²')
findecoration = re.compile(r'装修情况:(.*?)<')
findstreet = re.compile(r'              (.*?)            </div>')


price_total = []
price_per = []
findprice_total = re.compile(r'价格:(.*?)万 元/月')
findprice_per = re.compile(r'单价:(.*?)元/m²/天')  


for page in range(1, 86):
    # 读取每一页url
    url = baseurl + str(page)
    head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
    request = urllib.request.Request(url, headers = head)
    response = urllib.request.urlopen(request)
    html = response.read().decode('utf-8')
    soup = BeautifulSoup(html,'html.parser')
    
    # 整理一页的信息
    each = []
    for i in range(int(len(soup.find_all('div', class_ = 'address'))/3)):
        str1 = str(soup.find_all('div', class_ = 'address')[3*i])
        str2 = str(soup.find_all('div', class_ = 'address')[3*i+1])
        str3 = str(soup.find_all('div', class_ = 'address')[3*i+2])
        each.append(str1+str2+str3)
    
    # 获得信息
    for i in each:
        buildings.append(re.findall(findlocation, i)[0])
        district.append(re.findall(findlocation, i)[1])
        areas.append(re.findall(findlocation, i)[2])
        decoration.append(re.findall(findecoration, i)[0])
        domain.append(re.findall(finddomain, i)[0])
        streets.append(re.findall(findstreet, i)[0])

    for price in soup.find_all('div', class_ = 'mianji'):
        price = str(price)
        price_total.append(re.findall(findprice_total, price)[0])
        price_per.append(re.findall(findprice_per, price)[0])
        
        
        
# 保存导出数据  
raw_data = pd.DataFrame({'buildings':buildings,
                         'decoration': decoration,
                        'district':district,
                        'domain': domain,
                        'areas':areas,
                        'streets':streets,
                        'price_total':price_total,
                        'price_per':price_per
})
raw_data
  • 11
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值