优客逸家挂牌房源爬取

优客逸家挂牌房源爬取

背景

上次爬取了青客公寓各城市的挂牌房源信息,这次打算拿同类型的分散式集中公寓品牌优客逸家练练手,由于上次是有城市简称和网页总数的两个输入,只能算半自动化,这次决定重新设计一下,让程序自己判断是否到最后一页,一直到最后一页爬完程序运行结束。

问题分析及思路

由于要设计一个判断来判断是否到达最后一页,所以用到了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爬虫仅为学习交流,如有冒犯,请告知删。

延申阅读 青客公寓分城市爬取

优客逸家挂牌房源爬取

上一篇:boost::geometry::detail::tupled_output_has用法的测试程序


下一篇:[C++]迭代器实现及二维链表实现