1、 背景
本实例爬取小猪网沈阳房源信息,使用request、bs4。
简单爬取title、address、price、name、sex等信息。未保存信息。
2、场景分析
2.1 小猪网沈阳(https://sy.xiaozhu.com/)打开后有一个房源列表
右侧为房源图表列表
2.2 房源列表分析
a、使用chrome浏览器
b、F12进行源文件分析
c、鼠标点源文件左上角的“箭头”,再点任一房源位置
d、找到源代码中的房源a链接部分,右键a链接后“copy”->“copy selector”,复制需要css 选择器供bs4使用
2.3 房源详细信息分析
点击2.2房源列表中的任一房源,进入房源详细信息。需要爬虫的具体内容选择方法同上
2.3 房源page信息分析
房源列表分析页面的下面有数字的列表,使用2.2的方法,可以获取到不同page的url信息
功能实现
import requests # 导入爬虫模块
from bs4 import BeautifulSoup #导入分析库模块
result = requests.get('https://sy.xiaozhu.com/')
soup = BeautifulSoup(result.text,'lxml')
房源url列表
houre_links = soup.select('#page_list > ul > li > a')
打印房源url
for lik in houre_links:
print(lik['href'])
# houre_links #page_list > ul > li:nth-child(2) > a
https://sy.xiaozhu.com/fangzi/24328800703.html
https://sy.xiaozhu.com/fangzi/91690139803.html
https://sy.xiaozhu.com/fangzi/11307220860.html
。。。
使用css选择器获取房源基本信息
rs = requests.get('https://sy.xiaozhu.com/fangzi/5950030916.html')
soup1 = BeautifulSoup(rs.text, 'lxml')
title = soup1.select('div > h4 > em')[0].get_text()
address = soup1.select('div.con_l > div.pho_info > p')[0]['title']
price = soup1.select('#pricePart > div.day_l > span')[0].get_text()
image_url = soup1.select('#curBigImage')[0]['src']
name = soup1.select('.lorder_name')[0].get_text()
sex = soup1.select('.member_boy_ico')[0].get_text()
保存房源图片,需要加上headers,否则爬取图片会报403错误
import os
def save_house_image(url, name):
name = str.replace(name, '/', '')
os.makedirs('images', exist_ok=True)
headers = {
'Referer': url,
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36'
}
with open('images/' + name + '.png', 'wb') as f:
rs = requests.get(url,headers=headers)
rs.raise_for_status()# 此处可以加上try…except…处理异常
for chunk in rs.iter_content(100000): #保存二进制文件
f.write(chunk)
获取房源详细信息
def get_info(url):
rs = requests.get(url)
soup1 = BeautifulSoup(rs.text, 'lxml')
title = soup1.select('div > h4 > em')[0].get_text() # 标题
address = soup1.select('div.con_l > div.pho_info > p')[0]['title'] # 地址
price = soup1.select('#pricePart > div.day_l > span')[0].get_text() # 价格
image_url = soup1.select('#curBigImage')[0]['src'] # 图像URL
name = soup1.select('.lorder_name')[0].get_text() # 房主昵称
sex = '男'
try:
sex = soup1.select('.member_boy_ico')[0].get_text() # 房主性别
if sex:
real_sex = sex
else:
real_sex = '女'
except:
real_sex = '女'
# 返回的房源详细信息,根据需要可以选择保存
info = {
'title': title,
'address': address,
'price': price,
'image_url': image_url,
'name': name,
'sex': real_sex
}
# print(info)
# 保存图片
save_house_image(image_url, title)
return info
获取房源列表页面所有房源的url列表和能获取到的page页面url信息
import requests
from bs4 import BeautifulSoup
def get_links(url):
result = requests.get(url)
soup = BeautifulSoup(result.text,'lxml')
# 获取当前页
active_page = soup.select('.active_link')[0].get_text()
print('当前页为:%s' % active_page)
# 获取当前可以获取的page列表
page_list = soup.select('div.pagination_v2.pb0_vou a') #page_list > div.pagination_v2.pb0_vou
for page_num in page_list:
try: # 有些page是< > ...开头通过轻质int类型转换异常抛弃
num = int(page_num.get_text())
# 将page页保存在字典中
page_lists[num] = page_num['href']
except:
print('无用page页面,pass')
houre_links = soup.select('#page_list > ul > li > a')
for lik in houre_links:
print(lik['href']) # 打印房源详情页url
get_info(lik['href']) # 调用方法获取房源的详细信息
递归函数从第一页开始爬取
刚开始用while循环会重复爬取,没详细定位,改完递归函数后OK
finsh_num = {} # 已完成爬取的page页字典
page_lists = {1: 'https://sy.xiaozhu.com/'} # 获取到的全部page页字典
def xiaozhu_spider():
for k in list(page_lists):
if k not in finsh_num:
get_links(page_lists[k])
finsh_num[k] = page_lists[k]
print('已完成爬取页面: %s' %finsh_num)
print('全部页面: %s' % page_lists)
# 已完成爬取的page页 等于 获取到的全部page页相同表示爬取完毕
if finsh_num == page_lists:
print('已全部爬取完毕')
return
else:#没有爬取完进入递归
xiaozhu_spider()
xiaozhu_spider()