优客逸家挂牌房源爬取
背景上次爬取了青客公寓各城市的挂牌房源信息,这次打算拿同类型的分散式集中公寓品牌优客逸家练练手,由于上次是有城市简称和网页总数的两个输入,只能算半自动化,这次决定重新设计一下,让程序自己判断是否到最后一页,一直到最后一页爬完程序运行结束。
问题分析及思路由于要设计一个判断来判断是否到达最后一页,所以用到了while语句,并且是否到达最后一页作为判断条件,所以最后一页需要单独再爬一下,这样整个程序只需要运行一次,采用模块化设计,定义了 get_nextpage() 函数来获取下一页网址和最后一页网址,定义了 get_items_link() 函数来获取每一页房源列表的详情地址,然后通过第三个函数 get_detail_items() 进入详情页获取详情字段,最后用一个主函数 main() 把这几个函数整合起来,分析详情页发现可以获取 区域,板块,小区名称,房源标题,房源代码,价格,楼层,地址 等关键信息,所以在创建表的时候要一条一条的设计,最后爬虫要设计程序挂起时间 time.sleep(),尽量让对方服务器压力小点。
完整代码
# -*- coding: utf-8 -*-
"""
Created on Wed Jul 31 15:48:46 2019
title:uoko
@author: 帅帅de三叔
"""
import requests #导入请求模块
import time #导入时间模块
from bs4 import BeautifulSoup #导入网页解析模块
import pymysql #导入连接数据库模块
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"} #构造请求头
print("start connecting database uoko……\n")
db=pymysql.Connect('localhost','root','123456','uoko',charset='utf8') #链接到数据库uoko
cursor=db.cursor() #获取游标
cursor.execute("drop table if exists uoko_cd") #重新创建表
print("connect successfully,start creating table uoko_cd in database uoko\n")
c_sql="""create table uoko_cd(
district varchar(15),
plate varchar(15),
community varchar(15),
title varchar(50),
code varchar(15),
price varchar(15),
floor varchar(6),
address varchar(40)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8""
cursor.execute(c_sql)
print("table uoko_cd has been created\n")
def get_nextpage(url): #定义获取下一页网址函数
host="http://www.uoko.com/"
answer=requests.get(url,headers=header)
soup=BeautifulSoup(answer.text,'lxml')
next_=soup.find("div",class_="pagenation").findAll("a")[-2]['href']
next_page=host+next_ #host加尾巴构造下一页网址
last_=soup.find("div",class_="pagenation").findAll("a")[-1]['href']
last_page=host+last_ #host加尾巴构造尾页网址
return next_page,last_page
def get_items_link(page_url): #获取房源列表详情页
detail_urls=[] #用来存放当前页所有房源详情页链接
host="http://www.uoko.com/"
answer=requests.get(page_url,headers=header)
soup=BeautifulSoup(answer.text,'lxml')
contents=soup.find("ul",class_="gallery").findAll("li",class_="gallery-item")
if contents:
for content in contents:
detail_url=host+content.find("a")['href']
detail_urls.append(detail_url)
#print(detail_url)
return detail_urls
def get_detail_items(detail_link): #定义获取详情页字段函数
response=requests.get(detail_link,headers=header) #对详情页发出请求
time.sleep(1) #进程挂起1秒
soup=BeautifulSoup(response.text,'lxml') #解析网页
district=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[2].find("address",class_="address col").findAll("a")[0].get_text() #区域
plate=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[2].find("address",class_="address col").findAll("a")[1].get_text() #板块
community=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[2].find("address",class_="address col").findAll("a")[2].get_text() #小区名称
title=soup.find("div",class_="detail-right").find("h2",class_="detail-tit").get_text().replace(" ","").strip() #房源名称
code=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[0].find("span",class_="detail-num col").get_text() #编号
price=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[1].find("b",id="price-claim").get_text() #价格
floor=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[3].find("div",class_="detail-cont").get_text().strip().split(' ')[1] #楼层
address=soup.find("div",class_="detail-table").findAll("div",class_="detail-row")[2].find("a",class_="address-detail").get_text() #小区名称
insert_data=("insert into uoko_cd(district,plate,community,title,code,price,floor,address)""values(%s,%s,%s,%s,%s,%s,%s,%s)") #空值插入格式
uoko_data=([district,plate,community,title,code,price,floor,address]) #待插入的一条数据
cursor.execute(insert_data,uoko_data)#执行插入操作
db.commit()#主动提交
print(district,plate,community,title,code,price,floor,address)
return district,plate,community,title,code,price,floor,address
def main(): #定义主函数
start_url="http://www.uoko.com/room/pg1/" #待请求的起始页
detail_urls=get_items_link(start_url) #获取首页的房源列表的链接
#print(detail_urls)
for detail_url in detail_urls:
#print(detail_url)
get_detail_items(detail_url) #进入详情页获取字段
next_page=get_nextpage(start_url)[0] #获取下一页连接
last_page=get_nextpage(start_url)[1] #获取最后一页连接
while next_page!=last_page: #while循环
item_links=get_items_link(next_page) #下一页的房源列表详情页链接
for links in item_links:
get_detail_items(links)
next_page=get_nextpage(next_page)[0] #更新下一页连接
print(next_page,last_page)
else:#对最后一页单独爬取
last_detail_links=get_items_link(last_page)
for last_detail_url in last_detail_links:
get_detail_items(last_detail_url) #补上最后一页房源信息内容
print("crawl finished")
if __name__=="__main__":
main()
免责申明
Python爬虫仅为学习交流,如有冒犯,请告知删。
延申阅读 青客公寓分城市爬取