爬虫案例4——爬取房天下数据

简介:个人学习分享,如有错误,欢迎批评指正

任务从房天下网中爬取小区名称、地址、价格和联系电话

目标网页地址:https://newhouse.fang.com/house/s/

一、思路和过程

目标网页具体内容如下:
​​​​
在这里插入图片描述

我们的任务是将上图中小区名称、地址、价格和联系电话对应爬下来。

1.定义目标URL

由于网页普遍具有反爬程序,不加修饰的直接访问网页可能会失败,所以第一步学会伪装自己。
如何伪装自己呢,可以通过找到正常访问网页时的访问状态,将自己的这次爬虫模拟成一次正常访问网页,因此我们的目标是找到正常访问网页时的User-Agent。User Agent中文名为用户代理,(简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等)。User-Agent就是你访问网页的身份证明。具体操作如下:

首先打开目标(/任意)网页,然后点击鼠标右键后选择检查打开网页的HTML 页面。
在这里插入图片描述

在HTML 页面里面依次点击网络,然后任意点一条网络请求(如果没有显示任何网络请求可以点击网页左上角的刷新),然后选择标头,下拉列表找到User-Agent,User-Agent后面那段内容就是我们用来伪装自己的身份码。

在这里插入图片描述

2.发送GET请求获取网页内容

通过上面的步骤我们获得了
url = ‘https://newhouse.fang.com/house/s/’

User-Agent:‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0’

接下来发起网页访问请求,代码如下:

import requests  # 引入requests库,用于发送HTTP请求
from lxml import etree  # 引入lxml库中的etree模块,用于解析HTML文档

# 定义目标URL,即要爬取的网页地址
url = 'https://newhouse.fang.com/house/s/'

# 定义HTTP请求头,其中包括User-Agent信息,用于伪装成浏览器进行访问
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0'
}

# 发送GET请求获取网页内容,并将响应内容存储在resp变量中
resp = requests.get(url, headers=headers)
# 设置响应内容的编码格式为utf-8,确保中文字符正常显示
resq.encoding = 'utf-8'
# 打印响应内容,检查获取到的HTML文本
print(resp.text)

查看print结果,我们发现成功获得了网页相关的html表达,

在这里插入图片描述

3.分析网页内容

接下来对html进行解析获得我们目标内容。
这里,我们需要借助工具xpath来辅助内容解析,xpath安装教程

安装成功后,按Ctrl+Shift+Alt 启动 xpath,网页上方出现如下图所示框,
在这里插入图片描述
找到目标内容方法
例:我们的目标是找到小区名字在html中的位置。点击如下图左边标记(1),该命令的含义是在网页中选择一个元素以进行检查,即当你把鼠标放在网页的某一位置,下面也会自动定位到html中该内容所在位置,如图所示,把鼠标放在北京城建·星誉BEIJING(2),下面显示小区名在html中所在位置(3)。
在这里插入图片描述

明确目标内容的位置。具体的,如下图所示,小区名北京城建·星誉BEIJING,它位于div class="nlcd_name"中的a里面。

在这里插入图片描述

因此,我们可以通过这个层层关系来找到目标所有小区名,借助刚才安装的工具xpath,下面一步步演示层层查找过程。
首先,在query中添加//div[@class=“nlcd_name”],可以发现右边的results将所有小区的名字返回了。

在这里插入图片描述

其次,加上筛选条件a得
在这里插入图片描述

同理,query中添加//div[@class=“nlcd_name”],可以发现右边的results将所有小区的地址返回了。
在这里插入图片描述

同理,query中添加//div[@class=“nhouse_price”],可以发现右边的results将所有小区的价格返回了。
在这里插入图片描述

同理,query中添加//div[@class=“tel”]/p/text(),可以发现右边的results将所有小区的联系方式返回了。

在这里插入图片描述

但是,我们发现上面只能取到单页的内容,而整个网页如下有很多页。
在这里插入图片描述
对于上述问题,我们通过对比下图情况,发现url地址不同的页码的url仅仅换了最后一个数字,数字即对应页码。

在这里插入图片描述在这里插入图片描述
因此进一步添加一个for循环来取得所有页的url地址,代码如下:

for i in range(4):
    # 构建每一页的URL
    url = f'https://newhouse.fang.com/house/s/b9{i}/'

    # 发送GET请求获取网页内容,并将响应内容存储在resq变量中
    resq = requests.get(url, headers=headers)
    # 设置响应内容的编码格式为utf-8,确保中文字符正常显示
    resq.encoding = 'utf-8'
    # 打印响应内容,检查获取到的HTML文本
    print(resq.text)

因此,通过xpath的可视化辅助,得上面地址
//div[@class="nlcd_name"]/a可以获取小区名称,//div[@class="address"]/a/@title可以获取小区地址,//div[@class="nhouse_price可以获取小区价格,//div[@class="tel"]/p/text()可以获取小区联系电话。

4.获取目标数据

上一步得到了目标数据的地址,接下来就是分别获得到目标数据,代码如下:

    # 使用etree.HTML方法将HTML文本解析为一个HTML文档对象
    e = etree.HTML(resq.text)

    # 使用XPath语法从HTML文档中提取出小区名称,并去除字符串前后的空白字符
    names = [n.strip() for n in e.xpath('//div[@class="nlcd_name"]/a/text()')]
    # 使用XPath语法从HTML文档中提取出小区地址
    addreses = e.xpath('//div[@class="address"]/a/@title')
    # 使用XPath语法从HTML文档中提取出小区价格,并去除多余的空白字符
    price = [pr.xpath('string(.)').strip() for pr in e.xpath('//div[@class="nhouse_price"]')]
    # 使用XPath语法从HTML文档中提取出联系电话
    tel = e.xpath('//div[@class="tel"]/p/text()')

5.保存数据

存为一个txt文件


    with open('fangtianxia.txt', 'w', encoding='utf-8') as f:
        # 使用zip函数将名称、地址、价格、电话数据组合在一起,逐行写入文件
        for na, ad, pr, te in zip(names, addreses, price, tel):
            # 写入格式为:红球号码:xxx 蓝球号码:xxx
            f.write(f'姓名:{na} 地址:{ad} 价格:{pr} 电话:{te}\n')

二、完整python代码

import requests  # 引入requests库,用于发送HTTP请求
from lxml import etree  # 引入lxml库中的etree模块,用于解析HTML文档
import pandas as pd  # 引入pandas库,用于处理和存储数据

# 定义HTTP请求头,其中包括User-Agent信息,用于伪装成浏览器进行访问
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0'
}

# 初始化一个空列表,用于存储爬取的数据
data = []

# 循环遍历4个页面,每个页面的URL末尾数字依次递增
for i in range(4):
    # 构建每一页的URL
    url = f'https://newhouse.fang.com/house/s/b9{i}/'

    # 发送GET请求获取网页内容,并将响应内容存储在resq变量中
    resq = requests.get(url, headers=headers)
    # 设置响应内容的编码格式为utf-8,确保中文字符正常显示
    resq.encoding = 'utf-8'
    # 打印响应内容,检查获取到的HTML文本
    print(resq.text)

    # 使用etree.HTML方法将HTML文本解析为一个HTML文档对象
    e = etree.HTML(resq.text)

    # 使用XPath语法从HTML文档中提取出小区名称,并去除字符串前后的空白字符
    names = [n.strip() for n in e.xpath('//div[@class="nlcd_name"]/a/text()')]
    # 使用XPath语法从HTML文档中提取出小区地址
    addreses = e.xpath('//div[@class="address"]/a/@title')
    # 使用XPath语法从HTML文档中提取出小区价格,并去除多余的空白字符
    price = [pr.xpath('string(.)').strip() for pr in e.xpath('//div[@class="nhouse_price"]')]
    # 使用XPath语法从HTML文档中提取出联系电话
    tel = e.xpath('//div[@class="tel"]/p/text()')

    with open('fangtianxia.txt', 'w', encoding='utf-8') as f:
        # 使用zip函数将名称、地址、价格、电话数据组合在一起,逐行写入文件
        for na, ad, pr, te in zip(names, addreses, price, tel):
            # 写入格式为:红球号码:xxx 蓝球号码:xxx
            f.write(f'姓名:{na} 地址:{ad} 价格:{pr} 电话:{te}\n')

结~~~

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在上一篇文章中,我们介绍了如何通过Java代码模拟浏览器行为来爬取携程网站上的酒店列表数据。本篇文章将继续介绍如何通过Java代码获取酒店详情页面的数据。 1. 获取酒店详情页面URL 在上一篇文章中,我们已经可以获取到酒店列表页面的数据。接下来,我们需要从列表页面中获取每个酒店的详情页面URL。我们可以通过以下代码来获取URL: ```java // 获取酒店详情页面URL Elements hotelLinks = doc.select(".hotel_item a[href^=//hotels.ctrip.com/hotel/]"); for (Element link : hotelLinks) { String href = link.attr("href"); hotelUrls.add("http:" + href); } ``` 这里我们使用了Jsoup框架提供的选择器功能,选取class为“hotel_item”的元素,然后再选取其中的a标签,并且href属性值以“//hotels.ctrip.com/hotel/”开头的元素。然后再遍历这些元素,获取其中的href属性值并加上“http:”前缀,即是酒店详情页面的URL。 2. 解析酒店详情页面数据 获取到酒店详情页面的URL后,我们需要再次模拟浏览器行为,访问该URL并获取页面数据。我们可以通过以下代码来实现: ```java // 获取酒店详情页面数据 for (String url : hotelUrls) { Document hotelDoc = Jsoup.connect(url).userAgent(USER_AGENT).get(); String hotelName = hotelDoc.select(".hotel_intro dt").text(); String address = hotelDoc.select(".hotel_address a").text(); String score = hotelDoc.select(".hotel_score .score_num").text(); String commentNum = hotelDoc.select(".hotel_judgement .hotel_judgement_judgement").text(); String price = hotelDoc.select(".hotel_intro .hotel_price span").text(); hotels.add(new Hotel(hotelName, address, score, commentNum, price)); } ``` 这里我们同样使用了Jsoup框架来获取页面数据。首先,我们遍历所有酒店详情页面的URL,然后通过Jsoup.connect()方法连接到该URL并获取页面数据。接着,我们使用选择器选取需要的元素,例如酒店名称、地址、评分、评论数和价格等,并将其保存到一个自定义的Hotel对象中。最后,我们将所有的Hotel对象添加到一个列表中,以便后续的数据处理。 3. 数据保存 获取到所有酒店的数据后,我们可以将其保存到本地文件中,也可以将其保存到数据库中。这里我们使用了JDBC连接MySQL数据库,并将数据保存到一个名为“hotels”的表中。以下是保存数据的代码: ```java // 保存酒店数据数据库 Connection conn = null; PreparedStatement stmt = null; try { Class.forName(JDBC_DRIVER); conn = DriverManager.getConnection(DB_URL, USER, PASS); String sql = "INSERT INTO hotels (name, address, score, comment_num, price) VALUES (?, ?, ?, ?, ?)"; stmt = conn.prepareStatement(sql); for (Hotel hotel : hotels) { stmt.setString(1, hotel.getName()); stmt.setString(2, hotel.getAddress()); stmt.setString(3, hotel.getScore()); stmt.setString(4, hotel.getCommentNum()); stmt.setString(5, hotel.getPrice()); stmt.executeUpdate(); } } catch (SQLException se) { se.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (stmt != null) stmt.close(); } catch (SQLException se2) { } try { if (conn != null) conn.close(); } catch (SQLException se) { se.printStackTrace(); } } ``` 这里我们使用了JDBC框架来连接数据库,并执行SQL语句将酒店数据保存到数据库中。最后,我们需要在finally块中关闭数据库连接和语句对象,以释放资源。 总结 本篇文章介绍了如何通过Java代码获取携程网站上的酒店详情页面数据,并将其保存到MySQL数据库中。这个过程涉及到了许多技术,例如模拟浏览器行为、页面数据解析、数据库连接等。通过这个案例,我们可以更好地理解Java爬虫的实现原理和技术要点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值