批量爬取链家房源信息

Python 爬虫get请求

http get请求:明文向服务器发起资源获取的请求
post:向服务器传递信息
get:向服务器获取信息
get请求常见使用方法:
  urllib get
  requests get

在爬虫方向
  除了模拟登陆之外,大部分的请求是get
1、get请求常见使用方法
  网站分类
  网站分页
  搜索关键字
  瀑布流参数
2、get请求的格式:
  Get请求以问号开始,以&符合为分割,参数以键等于值的形式进行传递
  批量爬取链家房源信息_第1张图片
我们在爬虫面对get请求的时候,要分清get请求和路径请求,接下来我们通过一个例子来认识get请求.
爬取链家房产信息,分析链家网站租房页面特色,抓包分析,确定网页指定的包。
这里我们需要打开一个新的无痕窗口,并按F12进入开发者工具,查看各种包及源代码。
批量爬取链家房源信息_第2张图片
查看请求头部,获取我们可以使用的请求信息
批量爬取链家房源信息_第3张图片
进行网页功能点击试探
批量爬取链家房源信息_第4张图片
访问区域的时候,我们发现了新的链接请求
批量爬取链家房源信息_第5张图片
我们再访问第二页看看如何变化
批量爬取链家房源信息_第6张图片
接下来我们就可以对网页结构进行分析了
批量爬取链家房源信息_第7张图片
结构分析,除非要筛选的数据很多,否则知道大概,在代码编写的时候,按照xpath或者bs再次进行分析。
开始代码编写:
  我们今天采用urllib模块,urllib在Python2的时候,被划分为了urllib、urllib2两个模块,但是由于这两个模块功能重复,比如都拥有urlopen方法,所以,在Python3将urllib和urllib2整合为新的模块,按照功能划分为5个子模块
  Error 处理爬虫请求工程当中的错误
    拥有try,except捕获,或者raise错误诱发
  Parse 请求数据封装
  Request 请求功能
  Response 响应功能
  Robotparser 机器人(爬虫)协定
批量爬取链家房源信息_第8张图片
接下来我们先完成当前页面的源码获取,代码如下:

#coding:utf-8

from urllib import request

#请求的地址和身份参数
url = "https://cd.lianjia.com/zufang/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
#封装请求,这里没有发起请求
req = request.Request(url = url,headers = headers)
#使用urllib自带的请求方法发起请求,urlopen可以像浏览器一样向服务网发起请求,但是不记录服务器下发的识别
respone = request.urlopen(req)
#urllib返回字符串对象,通常以文件的格式进行返回
result = respone.read().decode() #python3 版本,文件对象读返回的是字节
#输出结果
print(result)

效果如下:
批量爬取链家房源信息_第9张图片

完成源码当中数据筛选

上面的代码我们完成了数据的爬取,但是,除了我们想要的数据,还有大段的HTML
我们需要的数据有
Name 房屋名称
  Address 房屋地址
  Style 房屋样式
  Size 房屋尺寸
  Price 房屋价格
我们首先以房屋名称为例子写一下xpath

#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author     : ALLEN
from urllib import request
from lxml import etree
#请求的地址和身份参数
url = "https://cd.lianjia.com/zufang/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
#封装请求,这里没有发起请求
req = request.Request(url = url,headers = headers)
#使用urllib自带的请求方法发起请求,urlopen可以像浏览器一样向服务网发起请求,但是不记录服务器下发的识别
respone = request.urlopen(req)
#urllib返回字符串对象,通常以文件的格式进行返回
result = respone.read().decode() #python3 版本,文件对象读返回的是字节
#输出结果
# print(result)
#构建HTML匹配对象
html = etree.HTML(result)
#进行xpath匹配
house_list = html.xpath('//ul[@id="house-lst"]/li/div[@class="info-panel"]/h2/a')

for house in house_list:
    name = house.text
    print(name)

效果如下:
批量爬取链家房源信息_第10张图片
但是在工作当中,由于web2.0构建出了相当多复杂的结构,我们需要知道,xpath匹配成功,放回的还是xpath对象,也就是还可以进行匹配,由于这个特性,我们的的xpath可以写成下面这样
我们对要筛选的数据按照HTML结构进行划分
批量爬取链家房源信息_第11张图片
我们将房屋名称进行单独匹配
将房屋样式、大小、和地址进行统一匹配
将价格单独匹配,匹配思路如下
首先匹配完整的一个里下面的信息块儿
批量爬取链家房源信息_第12张图片
其次通过对第一个子块儿匹配房屋名称
批量爬取链家房源信息_第13张图片
对第二个子块儿进行匹配,匹配房屋样式、大小、地址
批量爬取链家房源信息_第14张图片
第三个子块儿匹配价格
批量爬取链家房源信息_第15张图片
代码如下:

#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author     : ALLEN
from urllib import request
from lxml import etree
#请求的地址和身份参数
url = "https://cd.lianjia.com/zufang/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
}
#封装请求,这里没有发起请求
req = request.Request(url = url,headers = headers)
#使用urllib自带的请求方法发起请求,urlopen可以像浏览器一样向服务网发起请求,但是不记录服务器下发的识别
respone = request.urlopen(req)
#urllib返回字符串对象,通常以文件的格式进行返回
result = respone.read().decode() #python3 版本,文件对象读返回的是字节
#输出结果
# print(result)
#构建HTML匹配对象
html = etree.HTML(result)
#进行xpath匹配
house_list = html.xpath('//ul[@id="house-lst"]/li/div[@class="info-panel"]')

for house in house_list:
    #当前的house就是一个xpath对象
    house_name = house.xpath('h2/a')[0] #注意,xpath匹配哪怕一个返回的也是列表
    name = house_name.text

    #然后进行样式、大小、和地址的匹配,我们称这个匹配为房屋的描述
    house_description = house.xpath('div[@class="col-1"]')[0]
    house_style = house_description.xpath('div[@class="where"]/span[@class="zone"]/span')[0]
    style = house_style.text.strip()

    house_size = house_description.xpath('div[@class="where"]/span[@class="meters"]')[0]
    size = house_size.text

    house_address = house_description.xpath('div[@class="other"]/div[@class="con"]/a')[0]
    address = house_address.text

    #然后进行价格匹配
    house_price = house.xpath('div[@class="col-3"]/div[@class="price"]/span')[0]
    price = house_price.text

    #进行信息的汇总
    result_dict = {
        "address": address,
        "name": name,
        "style": style,
        "size": size,
        "price": price
    }
    content = "%(address)s-%(name)s[%(style)s]:%(size)s:%(price)s"%result_dict

    print(content)


效果如下:
批量爬取链家房源信息_第16张图片

完成批量爬取

代码如下:

#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author     : ALLEN
from urllib import request
from lxml import etree
def getHouse(page):
    house_data = []
    for p in range(1, page + 1):
        if p == 1:
            url = "https://cd.lianjia.com/zufang/"
        else:
            url = "https://cd.lianjia.com/zufang/pg%s/" % p

        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
        }
        #请求的地址和身份参数
        # url = "https://cd.lianjia.com/zufang/"
        # headers = {
        #     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
        # }
        #封装请求,这里没有发起请求
        req = request.Request(url = url,headers = headers)
        #使用urllib自带的请求方法发起请求,urlopen可以像浏览器一样向服务网发起请求,但是不记录服务器下发的识别
        respone = request.urlopen(req)
        #urllib返回字符串对象,通常以文件的格式进行返回
        result = respone.read().decode() #python3 版本,文件对象读返回的是字节
        #输出结果
        # print(result)
        #构建HTML匹配对象
        html = etree.HTML(result)
        #进行xpath匹配
        house_list = html.xpath('//ul[@id="house-lst"]/li/div[@class="info-panel"]')

        for house in house_list:
            #当前的house就是一个xpath对象
            house_name = house.xpath('h2/a')[0] #注意,xpath匹配哪怕一个返回的也是列表
            name = house_name.text

            #然后进行样式、大小、和地址的匹配,我们称这个匹配为房屋的描述
            house_description = house.xpath('div[@class="col-1"]')[0]
            house_style = house_description.xpath('div[@class="where"]/span[@class="zone"]/span')[0]
            style = house_style.text.strip()

            house_size = house_description.xpath('div[@class="where"]/span[@class="meters"]')[0]
            size = house_size.text

            house_address = house_description.xpath('div[@class="other"]/div[@class="con"]/a')[0]
            address = house_address.text

            #然后进行价格匹配
            house_price = house.xpath('div[@class="col-3"]/div[@class="price"]/span')[0]
            price = house_price.text

            #进行信息的汇总
            result_dict = {
                "address": address,
                "name": name,
                "style": style,
                "size": size,
                "price": price
            }
            content = "%(address)s-%(name)s[%(style)s]:%(size)s:%(price)s"%result_dict

            print(content)
            house_data.append(result_dict)
    return house_data
if __name__ == "__main__":
    getHouse(5)


完成灵活爬取

代码如下:

#! /usr/bin/env python3
# -*- coding : utf-8 -*-
# Author     : ALLEN
from urllib import request
from lxml import etree
def getHouse(addr,page):
    house_data = []
    # for p in range(1, page + 1):
    #     if p == 1:
    #         url = "https://cd.lianjia.com/zufang/"
    #     else:
    #         url = "https://cd.lianjia.com/zufang/pg%s/" % p
    #
    #     headers = {
    #         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
    #     }
    #     #请求的地址和身份参数
    #     # url = "https://cd.lianjia.com/zufang/"
    #     # headers = {
    #     #     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
    #     # }
    for p in range(1, page + 1):
        if p == 1:
            url = "https://cd.lianjia.com/zufang/%s/" % addr
            Referer = "https://cd.lianjia.com/zufang/"
        elif p == 2:
            url = "https://cd.lianjia.com/zufang/%s/pg%s/" % (addr, p)
            Referer = "https://cd.lianjia.com/zufang/%s/" % addr
        else:
            url = "https://cd.lianjia.com/zufang/%s/pg%s/" % (addr, p)
            Referer = "https://cd.lianjia.com/zufang/%s/pg%s/" % (addr, p - 1)

        headers = {
            "Referer": Referer,
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
        }

        #封装请求,这里没有发起请求
        req = request.Request(url = url,headers = headers)
        #使用urllib自带的请求方法发起请求,urlopen可以像浏览器一样向服务网发起请求,但是不记录服务器下发的识别
        respone = request.urlopen(req)
        #urllib返回字符串对象,通常以文件的格式进行返回
        result = respone.read().decode() #python3 版本,文件对象读返回的是字节
        #输出结果
        # print(result)
        #构建HTML匹配对象
        html = etree.HTML(result)
        #进行xpath匹配
        house_list = html.xpath('//ul[@id="house-lst"]/li/div[@class="info-panel"]')

        for house in house_list:
            #当前的house就是一个xpath对象
            house_name = house.xpath('h2/a')[0] #注意,xpath匹配哪怕一个返回的也是列表
            name = house_name.text

            #然后进行样式、大小、和地址的匹配,我们称这个匹配为房屋的描述
            house_description = house.xpath('div[@class="col-1"]')[0]
            house_style = house_description.xpath('div[@class="where"]/span[@class="zone"]/span')[0]
            style = house_style.text.strip()

            house_size = house_description.xpath('div[@class="where"]/span[@class="meters"]')[0]
            size = house_size.text

            house_address = house_description.xpath('div[@class="other"]/div[@class="con"]/a')[0]
            address = house_address.text

            #然后进行价格匹配
            house_price = house.xpath('div[@class="col-3"]/div[@class="price"]/span')[0]
            price = house_price.text

            #进行信息的汇总
            result_dict = {
                "address": address,
                "name": name,
                "style": style,
                "size": size,
                "price": price
            }
            content = "%(address)s-%(name)s[%(style)s]:%(size)s:%(price)s"%result_dict

            print(content)
            house_data.append(result_dict)
    return house_data
if __name__ == "__main__":
    getHouse("gaoxin7",5)


在上面代码的基础上,还可以完成对房产经纪人姓名和电话的爬取,然后汇总到最后的结果。这个部分将会在以后更新
如果对爬虫感兴趣,可以访问这个网址点击这里
这里有很多关于python方面的爬虫链接教程

你可能感兴趣的:(笔记,爬虫)