爬虫:使用beautifulsoup和requests抓取链家数据之二:抓取所有房源

趁着元旦假期,总算把一直想做但一直没做的爬虫起了个头,上一篇写了爬虫的基础代码,这一篇,就是正儿八经开始抓所有的房子信息了。
先说遇到的坑:
1、按第一篇直接进二手房的链接,只有3000个房源,这已经提过了。
2、房源里是没有房源位于哪个区的信息的,对数据分析而言,等于缺了一个重要信息,完全没法用了。
3、原来的想法是在title这个class里面抓房源ID,但是发现有一些房源,在这里是没有房源ID的,必须另找。
4、在跑的时候有报错,不知道是什么原因,直接暴力用try跳过去了。
5、有很多车位信息,其实我是不需要的,但是也抓进来了。
6、第一篇里CSV文件中“区”显示的是拼命,没有汉字,不直观。
7、每天都要抓的数据,区分文件名的时间和抓取时间需要手工加进去。
以下是代码,对于坑1,2,解决办法就是通过每个区进去,找对应的小区,然后进入小区的具体页面去找房源,这样就能记录房源的“区”信息了。
坑3的解决办法就是直接找了另一个class,代码里有。坑5的解决办法是用了一个if,在房子信息里开头标记为车位的,直接就不记录了
坑6:用字典解决
坑7:用import datetime解决

import requests
from bs4 import BeautifulSoup
import re
import math
import datetime
def get_xiaoqu():
    # 先列出各区的拼音
    area = {'siming': '思明区', 'jimei': '集美区', 'huli': '湖里区', 'tongan': '同安区', 'xiangan': '翔安区', 'haicang': '海沧区'}
    with open(r'c:\lianjia'+str(datetime.date.today())+r'.csv', 'a',encoding='utf-8') as f:
        f.write('{},{},{},{},{},{},{},{},{},{},{},{},{},{},\n'.format('区','房源编号', '小区', '商圈', '户型', '面积', '朝向', '户型', '装修', '年代','总价', '单价', '抓取时间','标题'))
        for a in area: # 对各区做循环
        	print(area.get(a))
            xiaoqu_url = [] # 放一个空列表,用来放各小区的链接
            url1 = 'https://xm.lianjia.com/xiaoqu/'+str(a)
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66'
            }
            html = requests.get(url1,headers=headers).text
            soup = BeautifulSoup(html,'html.parser')
            # print(soup)
            # 由于各区的小区数量是不一样d,链接的页数也就不一样,因此需要抓出所有小区数量,再根据数量倒推页数
            numbers = soup.find('h2',{'class':'total fl'}).find('span').text
            # print(numbers)
            page = math.ceil(int(numbers)/30)+1
            # print(page)
            for p in range(1,page): # 获取每页的小区信息
                url2 = 'https://xm.lianjia.com/xiaoqu/'+str(a)+str('/')+str('pg')+str(p)
                # print(url2)
                html1 = requests.get(url2, headers=headers).text
                soup1 = BeautifulSoup(html1, 'html.parser')
                # 所有小区的名字的都在ul-li的标签下
                infos = soup1.find('ul',{'class':'listContent'}).find_all('li')
                # print(infos)
                for info in infos: # 获取单个小区的具体信息
                    # xiaoqu_name = info.find('div',{'class':'title'}).find('a').get_text()
                    xiaoquurl = info.find('div', {'class': 'title'}).find('a').get('href')
                    sell_info = int(info.find('div',{'class':'xiaoquListItemSellCount'}).find('a').find('span').text)
                    # print(sell_info)
                    # 有的小区是0套房源,因此可以不用把链接放入list
                    if sell_info > 0:
                        # xiaoqu_url.append(xiaoquurl)
                        xiaoquID = re.sub(r'\D', '', xiaoquurl)
                        sell_page = math.ceil(int(sell_info)/30)+1
                        try:
                            for sp in range(1,sell_page):
                            # https: // xm.lianjia.com / ershoufang / pg2c3911057850738 /
                                url3 = r'https://xm.lianjia.com/ershoufang/pg' + str(sp) + 'c' + str(xiaoquID)
                                # print(url3)
                                headers = {
                                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66'
                                }

                                html = requests.get(url3, headers=headers).text
                                soup3 = BeautifulSoup(html, 'html.parser')
                                # print(soup)
                                houses = soup3.find('ul', {'class': 'sellListContent'}).find_all('li')
                                # print(infos)

                                for house in houses:
                                    # 获取房源ID
                                    # print(url3)
                                    house_id = house.find('div', {'class': 'unitPrice'}).get('data-hid')

                                    # 获取房源标题
                                    name = house.find('div', {'class': 'title'}).find('a').get_text()
                                    # 由于小区名字和小区所属商圈都在class=positionInfo这个切片下面,所以需要先将两个名字放入列表,然后分别提取
                                    weizhi = house.find('div', {'class': 'positionInfo'}).find_all('a')
                                    data_list = []
                                    for z in weizhi:
                                        data_list.append(z.get_text())
                                    xiaoqu = data_list[0]
                                    shangquan = data_list[1]
                                    # 有了小区名和位置,接下来就是看房子的具体信息,同样需要先转为列表然后切片
                                    houseinfo = house.find('div', {'class': 'houseInfo'}).get_text()
                                    houseinfolist = houseinfo.split('|')
                                    roominfo = houseinfolist[0]
                                    # print(roominfo)
                                    if roominfo != '车位 ':
                                        # 面积是浮点数,要用正则表达式提取
                                        mianji = re.findall(r'-?\d+\.?\d*e?-?\d*?', houseinfolist[1])[0]
                                        # print(mianji)
                                        chaoxiang = houseinfolist[2]
                                        zhuangxiu = houseinfolist[3]
                                        louceng = houseinfolist[4]
                                        nian = houseinfolist[5]
                                        # louxing = houseinfolist[6]
                                        # 接下来是总价
                                        totalprice = house.find('div', {'class': 'totalPrice'}).find('span').text
                                        # 接下来是每平单价,用正则表达式提取整数
                                        unitprice = re.sub('\D', '', house.find('div', {'class': 'unitPrice'}).find('span').text)
                                        # 接下来是存入csv

                                        f.write('{},{},{},{},{},{},{},{},{},{},{},{},{},{},\n'.format(area.get(a),house_id,xiaoqu,shangquan,roominfo,mianji,chaoxiang,zhuangxiu,louceng,nian,totalprice,unitprice,datetime.date.today(),name))
                        except:
                            break
                    else:
                        continue



            # return xiaoqu_url



get_xiaoqu()

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

White_Mountain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值