首页
学习
活动
专区
圈层
工具
发布
28 篇文章
1
【准备篇】js逆向分析破解之学习准备
2
js_cookie破解 | 爬虫遇到521还不会解决吗?
3
js_cookie破解好文 | 爬虫遇到521还不会解决吗?
4
爬虫系列(1)第一步肯定是先介绍介绍爬虫。
5
爬虫系列(2)爬虫需要使用什么工具,你知道吗?
6
爬虫系列(3)初窥urllib库。
7
爬虫系列(4)深入urllib库并初步了解URLError与Cookie。
8
爬虫系列(5)更简便Requests请求库使用介绍。
9
爬虫系列(6)数据提取--正则表达式。
10
爬虫系列(7)数据提取--Beautiful Soup。
11
爬虫系列(8)数据提取--扩展三种方法。
12
爬虫系列(9)爬虫的多线程理论以及动态数据的获取方法。
13
爬虫系列(10)Scrapy 框架介绍、安装以及使用。
14
爬虫系列(11)Scrapy 数据的提取和保存以及Pipeline的介绍。
15
爬虫系列(12)Scrapy 框架 - settings以及一个简单的小说案例实现。
16
爬虫系列(13)Scrapy 框架-CrawlSpider、图片管道以及下载中间件Middleware。
17
爬虫系列(14)Scrapy 框架-模拟登录-Request、Response。
18
爬虫系列(15)Splash 的使用。
19
爬虫系列(16)Scrapy 框架-爬取JS生成的动态页面。
20
爬虫系列(17)Scrapy 框架-分布式Scrapy-Redis以及Scrapyd的安装使用。
21
爬虫系列(18)Python-Spider。
22
爬虫实践 | 玩转百度地图API,带你看遍全国公园。
23
爬虫实践 | 维基百科深度优先与广度优先的开展
24
一个案例让你入门爬虫之Q房网爬虫实例
25
一个案例让你入门爬虫之二:Q房网爬虫多层页面爬取实例
26
一个案例让你入门爬虫之三:Q房网房源图片下载及多线程爬虫实现实例
27
广州地震了!地震到底离我们有多近,Python 爬虫带你了解
28
爬虫面试题 | 系统设计 —— 如何设计一个网页爬虫

一个案例让你入门爬虫之Q房网爬虫实例

首先,直入主题,你将在这个爬虫中学到:

  • requests请求库的使用
  • 基本爬虫三步的实现:网页请求下载,网页内容解析,解析内容存储
  • 多层页面的爬虫,爬取详细页
  • 图片的下载
  • 实现简单的多线程爬虫
  • 最基本的反爬虫应对措施

1.网站页面分析

目标网站的确认,本次爬取网站为深圳Q房网( https://shenzhen.qfang.com/),要爬取的是深圳市Q房网所有二手房的信息。

如图可知,深圳Q房网二手房的具体网址为( https://shenzhen.qfang.com/sale),共有39705套深圳二手房源,图中绿色所框的内容就是我们需要爬取的内容,包括:房源名称、户型、面积、装修类型、高低层、朝向、建成时间,每平方价格,具体地址等。

要爬取一个网站,首先要仔细的分析它的页面特点以及URL构造规律。可以分析一下它的翻页之后的URL规则,方便之后构造URL爬取全部信息。我们点击下一页也就是到达第二页发现URL变为( https://shenzhen.qfang.com/sale/f2),再点击下一页,URL变为( https://shenzhen.qfang.com/sale/f3),我们根据目前URL规则尝试一下,就是直接f后面加页码。

我们直接做一个尝试,验证一下我们的翻页URL规则,比如直接地址栏输入(https://shenzhen.qfang.com/sale/f66),验证如下图:

可以看到,完全没有问题,那么我们之后可以利用这个URL规则进行多页面爬取了。

2.编写Q房网深圳市二手房房源爬虫代码

首先,我们需要导入requests请求库和lxml库。本次房源信息保存在csv文件,所以也需要导入csv模块。其次,为了控制爬取速度,这也是一个反爬虫应对措施,还需要导入time模块,控制爬取速度目的是主要防止被Q房网的服务器反爬虫禁止。还没安装这些库或模块的,pip安装一下即可,这里不详细介绍了。

代码语言:javascript
代码运行次数:0
复制
import requests
from lxml import etree
import csv
import time

然后就是定义爬取函数spider(),在其中定义了一个请求头,因为服务器会通过读取请求头部的用户代理(User-Agent)来判断这个请求是正常浏览器或则是爬虫,为了防止服务器反爬虫禁止,这里定义一个请求头部。

代码语言:javascript
代码运行次数:0
复制
def spider():
    #定义爬虫头部
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
    }
    #使用for循环构造99页URL地址并get请求下来
    #为了防止爬取速度过快,在每一次get后,等待2秒
    pre_url = 'https://shenzhen.qfang.com/sale/f'
    for x in range(1,100):
        html = requests.get(pre_url+str(x),headers=headers)
        time.sleep(2)
        #用获取到的页面初始化etree,得到一个selector,然后在其上使用xpath提取所需数据
        selector = etree.HTML(html.text)

到这里我们已经可以爬取房源列表页了,据计算每一个房源列表页上大概有30套房源,每一套房源上包含一组我们需要爬去的信息。提取出这些房源数据有一个常用技巧:就是先提取提取每套房源整体的代码段,然后从代码段中提取所需要的信息数据。简单点说,就是先获取每一套房源的HTML源码,再从这一段HTML源码中解析出我们需要爬取的信息。

从上图中,我们知道每一套房源就是一个li标签,所以我们只需要获取所有的li标签就可以获取这一页中的每一个房源代码段。

提取的xpath为://div[@id='cycleListings']/ul//li[@class='clearfix'] ,这是每一个代码段的,总共有30个。

然后我们下面就可以解析每一个房源的具体需要爬取的信息了:

  • 房源名称(title): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[1]/a/text()
  • 户型(apartment): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[2]/text()
  • 面积(area): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[4]/text()
  • 装修类型(decoration_type): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[6]/text()
  • 层高(cenggao): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[8]/text()
  • 朝向(orientation): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[10]/text()
  • 竣工时间(build_finishtime): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[2]/span[12]/text()
  • 具体地点(location): //div[@id='cycleListings']/ul//li[@class='clearfix']/div[1]/p[3]/span[2]/a/text()
  • 总价格(total_price): //div[@id='cycleListings']/ul/li[@class='clearfix']//div[@class='show-price']

根据上面分析,xpath提取每一页每一套房源信息,代码如下:

代码语言:javascript
代码运行次数:0
复制
#先获取房源列表
house_list = selector.xpath("//div[@id='cycleListings']/ul//li[@class='clearfix']")
for house in house_list:
    title = house.xpath("/div[1]/p[1]/a/text()")[0]
    apartment = house.xpath("/div[1]/p[2]/span[2]/text()")[0]
    area = house.xpath("/div[1]/p[2]/span[4]/text()")[0]
    decoration_type = house.xpath("/div[1]/p[2]/span[6]/text()")[0]
    cenggao = house.xpath("/div[1]/p[2]/span[8]/text()")[0].strip()
    orientation = house.xpath("/div[1]/p[2]/span[10]/text()")[0]
    build_finishtime = house.xpath("/div[1]/p[2]/span[12]/text()")[0]
    location = house.xpath("/div[1]/p[3]/span[2]/a/text()")[0]
    total_price = house.xpath("//div[@class='show-price']")[0].strip()

然后就是把爬取的数据构造成一个list,然后进行保存。构造list和保存函数data_writer的代码如下;

代码语言:javascript
代码运行次数:0
复制
item = [title,apartment,area,decoration_type,cenggao,orientation,build_finishtime,location,total_price]
data_writer(item)
print('正在爬取',title)

def data_writer(item):
    with open('qfang_shenzhen_ershou.csv','a',encoding='utf-8',newline='') as f:
        writer = csv.writer(f)
        writer.writerow(item)

以追加'a'的形式打开一个csv文件(如果没有,系统会创建一个),设置编码方式为utf-8,为了防止每次打开添加数据时插入空行,设置newline=''。

最后编写,主函数即可完成一个简单的爬虫,代码如下:

代码语言:javascript
代码运行次数:0
复制
if __name__ == '__main__':
    spider()

完整代码如下:

代码语言:javascript
代码运行次数:0
复制
import requests
from lxml import etree
import csv
import time
def spider():
    #定义爬虫头部
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
    }
    #使用for循环构造99页URL地址并get请求下来
    #为了防止爬取速度过快,在每一次get后,等待2秒
    pre_url = 'https://shenzhen.qfang.com/sale/f'
    for x in range(1,100):
        html = requests.get(pre_url+str(x),headers=headers)
        time.sleep(2)
        #用获取到的页面初始化etree,得到一个selector,然后在其上使用xpath提取所需数据
        selector = etree.HTML(html.text)
        #先获取房源列表
        house_list = selector.xpath("//div[@id='cycleListings']/ul//li[@class='clearfix']")
        for house in house_list:
            title = house.xpath("/div[1]/p[1]/a/text()")[0]
            apartment = house.xpath("/div[1]/p[2]/span[2]/text()")[0]
            area = house.xpath("/div[1]/p[2]/span[4]/text()")[0]
            decoration_type = house.xpath("/div[1]/p[2]/span[6]/text()")[0]
            cenggao = house.xpath("/div[1]/p[2]/span[8]/text()")[0].strip()
            orientation = house.xpath("/div[1]/p[2]/span[10]/text()")[0]
            build_finishtime = house.xpath("/div[1]/p[2]/span[12]/text()")[0]
            location = house.xpath("/div[1]/p[3]/span[2]/a/text()")[0]
            total_price = house.xpath("//div[@class='show-price']")[0].strip()
            item = [title,apartment,area,decoration_type,cenggao,orientation,build_finishtime,location,total_price]
            data_writer(item)
            print('正在爬取',title)
def data_writer(item):
    with open('qfang_shenzhen_ershou.csv','a',encoding='utf-8',newline='') as f:
        writer = csv.writer(f)
        writer.writerow(item)
if __name__ == '__main__':
    spider()

以上就完成了一个最简单的爬虫案例,你也算是懂的爬虫了,入门爬虫了,这个案例会分成三个部分,会接下来继续更新,接下来的两个案例为:

  • 一个案例让你入门爬虫之Q房网爬虫多层页面爬取实例
  • 另一个是一个案例让你入门爬虫之Q房网房源图片下载及多线程爬虫实现实例
下一篇
举报
领券