import requests
import time
import re
from lxml import html
from pymongo import MongoClient
# 打开链家网
def get_areas(url, col):
print('start grabing areas')
# 用户代理
headers = {
'User-Agent': 'Mozilla/5.0 (Xll;Linux x86_64) AppleWebkit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.108 Safari/537.36'
}
# 获取网页链接以及设置伪装身份
res = requests.get(url + '/zufang', headers=headers)
# 将源码转化为能被XPath匹配的格式
content = html.etree.HTML(res.text)
# 使用正则匹配所有出售房源的区域名存储在一个数组里
areas = content.xpath("//ul[@data-target='area']/li/a/text()")
print(areas)
# 使用正则匹配所有区域名的url存储在一个数组里
areas_link = content.xpath("//ul[@data-target='area']/li/a/@href")
# 遍历每个区域下的url链接,默认给12个地区来循环
for i in range(1, 12):
# 获取每一个区域名称
area = areas[i]
print(area)
# 获取每一个区域名称对应的url
area_link = areas_link[i]
# 把url拼接成对应区域的url
link = url + area_link
print(link)
print("开始抓取页面:" + link)
# 调用进入区域的函数
get_pages(area, link, col)
# 进入区域
def get_pages(area, area_link, col):
# 当获取不到页数时捕获异常
try:
headers = {
'User-Agent': 'Mozilla/5.0 (Xll;Linux x86_64) AppleWebkit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.108 Safari/537.36'
}
# 打开网页
res = requests.get(area_link, headers=headers)
# 使用正则匹配这个区域的房源分成多少页数来展示的总数
pages = int(re.findall("data-totalPage=(\d+) data-curPage", res.text)[0])
print("这个区域有" + str(pages) + "页")
# 遍历每一页
for page in range(1, pages + 1):
# 分析网页发现每一页的url都有pg加上迭代的数字
url = area_link + 'pg' + str(page)
print(url)
print("开始抓取第" + str(page) + "页的信息")
# 调用进入每一页的函数
get_house_info(area, url, col)
except Exception:
time.sleep(5) # 捕获异常时程序暂停5秒
# 爬取每一页的房源信息
def get_house_info(area, url, col):
# 创建一个数组存储每一页的房源
hlist = []
headers = {
'User-Agent': 'Mozilla/5.0 (Xll;Linux x86_64) AppleWebkit/537.36 (KHTML,like Gecko) Chrome/63.0.3239.108 Safari/537.36'
}
# time.sleep(2)
# 捕获异常
try:
# 打开网页
res = requests.get(url, headers=headers)
# 建立HTMl的DOM树结构为接下来的正则匹配所用的
content = html.etree.HTML(res.text)
# 每一页大概有30个房源信息遍历每一个房源信息
for i in range(30):
# 正则匹配每一个房源的小区名
title = content.xpath("//div[@class='content__list--item--main']/p[2]/a[3]/text()")[i]
# 正则匹配每一个房型
room_type = content.xpath("//div[@class='content__list--item--main']/p[2]/text()[7]")[i].strip()
# 正则匹配每一个房源的面积 strip作用是清除空格
square = content.xpath("//div[@class='content__list--item--main']/p[2]/text()[5]")[i].strip()[:-1]
# 正则匹配每一个房源的朝向
position = content.xpath("//div[@class='content__list--item--main']/p[2]/text()[6]")[i].strip()
# 正则匹配房源位置
detail_place = content.xpath("//div[@class='content__list--item--main']/p[1]/a/text()")[i]
# 正则匹配房源的价格
price = content.xpath("//div[@class='content__list--item--main']/span/em/text()")[i]
# 创建一个json类型的数组来存储每一栋房子的数据
item = {
"area": area,
"title": title,
"room_type": room_type,
"position": position,
"detail_place": detail_place,
"price": int(price),
"square": int(square),
}
# 把每一页的数据添加数组中
hlist.append(item)
# 把每一页的数据插入到MongoDB中存储
col.insert(hlist)
except Exception as e:
print('连接错误,重新连接......')
time.sleep(5)
def main():
print('start!')
url = 'https://nn.lianjia.com'
# Mongo的连接IP和端口号
client = MongoClient('localhost', 27017)
# 获取数据库,没有则创建
db = client.get_database("zufang")
# 创建表
col = db.get_collection("nanning")
# 存储数据
get_areas(url, col)
# 关闭Mongo
client.close()
print('over!')
#程序入口
if __name__ == '__main__':
main()
链家网
最新推荐文章于 2021-12-20 19:14:54 发布