爬取安居客住房信息

本来这两天是打算继续学习数据挖掘的,但是在偶然的机会下突然想去爬取下安居客的房源信息,写的程序代码比较乱,基本没有什么健壮性,函数各个功能也没有分开。感觉对于爬虫来说数据处理是一大重要的问题,本来我已经把大的方向写好了,但是总是报一些细节的错误,就是在哪里各种的调试,花费了好长时间。最后的爬取的结果如下面的图所示。在这里插主要入图片描述 主要是整合的数据稍微的困难一点,其他的下面就直接先上代码,这个代码写的比较差,也不够优美,实在是不想在改了,调优花费的时间比写爬虫还要多。

import requests
from bs4 import BeautifulSoup
import re
from redis import StrictRedis
import xlrd
import xlwt
from xlutils.copy import copy
red = StrictRedis(host='localhost', port=6379, db=0)
s=requests.Session()#自动处理cookies,没有就无法访问详情页
redis1 = StrictRedis(host='localhost', port=6379, db=0)
global counts

counts=0#声明全局变量,用来统计爬取多少条的



def get_one_page(page):

    url='https://shenzhen.anjuke.com/sale/p'+str(page)#初始的url,爬虫从这开始
    header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0',


      }
    r=s.get(url=url,headers=header)

    url_info = re.findall('https:.*?time=\d{1,}',r.text)
    url_info_list=[]
    for info in url_info:
        # redis1.rpush('url_list', info)#这里一开始时打算用redis的但是总是报错就算了,数据库比列表性能好。
        url_info_list.append(info)#获取详情页url存在列表中
    #print(url_info_list)


    soup=BeautifulSoup(r.text,'lxml')
    #print(soup)
    house_info=soup.find_all('div',class_='house-title')
    house_details=soup.find_all('div',class_='details-item')
    house_price=soup.find_all('div',class_='pro-price')#获取详情页的房子价格等信息
    phone_list=[]#电话列表,用于存放电话信息
    contact_list=[]#联系人列表,用于存放联系人信息
    for url in url_info_list:
    # while redis1.lpop('url_list'):
        #url = redis1.lpop('url_list')#这里一开始时打算用redis的但是总是报错就算了,数据库比列表性能好。
        r = s.get(url=url, headers=header)
        soup1 = BeautifulSoup(r.text, 'lxml')
        try:###这里总是报错添加个异常处理
            contact = soup1.find('div', class_='brokercard-name').text[0:3]
            if contact:
                contact_list.append(contact)
            else:
                contact_list.append('佚名')#如果抓不到联系人信息,就补全防止异常
        except:
            pass

        if re.findall("im_broker_id = '(\d{4,})'", r.text)[0]:#这里也总是异常,添加个判断处理下
            broker_id = re.findall("im_broker_id = '(\d{4,})'", r.text)[0]
        else:
            continue
        prop_id1 = re.findall("house_id:'.*?'", r.text)
        prop_id = re.findall("(\d{4,})", prop_id1[0])[0]
        token = re.findall("token: '(.*?)',", r.text)[0]
        prop_city_id = re.findall("prop_city_id: '(\d{1,})',", r.text)[0]
        house_type = re.findall("house_type: '(\d{1,})'", r.text)[0]


        url1 = r'https://shenzhen.anjuke.com/v3/ajax/broker/phone/?'
        base = 'broker_id=' + broker_id + '&token=' + token + '&prop_id=' + prop_id + '&prop_city_id=' + prop_city_id + '&house_type=' + house_type + '&captcha='
        url2 = url1 + base #获取到broker_id , token等信息对其做拼接形成新的url
        res = s.get(url=url2, headers=header)#请求获得电话信息
        # print(res.text)
        last_info = re.findall('''"val":"(.*?)"''', res.text)
        phone_list.append(last_info[0].replace(' ',''))
        


    global counts
    for (info1,info2,info3,info4,info5)in zip(house_info,house_details,house_price,contact_list,phone_list):
    #for i in range(len(phone_list)):#遍历每个列表,将每个列表对应的第i个信息加入列表list_info。并写入excel。
        list_info=[]
        info_href=info1.a.attrs['href']
        #print(type(info1))
        info=info1.text.strip()
        inf=info2.text.strip()
        house_title=info.strip()
        house_detail=inf.strip()
        price=re.findall(r'(\d{2,}.)',info3.text)
        house_price=price[0]
        house_price_averge=price[1]
        print('xxxxxxxxxxxxxxxxxxxxxxx')
        counts+=1
        print(counts)
        list_info.append(house_title)
        list_info.append(house_detail)
        list_info.append(house_price.replace('万',''))
        list_info.append(house_price_averge.replace('元',''))
        list_info.append(info4.strip())
        list_info.append(info5)

        write_one_excel_xls_append(r'C:\Users\ASUS\Desktop\test_worm\details.xls', list_info)
def get_manypage(page):
    for i in range(page):
        get_one_page(i)

#写入excel表格
def write_excel_xls(path, sheet_name, value):
    index = len(value)  # 获取需要写入数据的行数
    workbook = xlwt.Workbook()  # 新建一个工作簿
    sheet = workbook.add_sheet(sheet_name)  # 在工作簿中新建一个表格
    for i in range(0, index):
        for j in range(0, len(value[i])):
            sheet.write(i, j, value[i][j])  # 像表格中写入数据(对应的行和列)
    workbook.save(path)  # 保存工作簿
    print("xls创建成功")
#行数据写入

def write_one_excel_xls_append(path, value):
    # 获取需要写入数据的行数
    workbook = xlrd.open_workbook(path)  # 打开工作簿
    sheets = workbook.sheet_names()  # 获取工作簿中的所有表格
    worksheet = workbook.sheet_by_name(sheets[0])  # 获取工作簿中所有表格中的的第一个表格
    rows_old = worksheet.nrows  # 获取表格中已存在的数据的行数
    new_workbook = copy(workbook)  # 将xlrd对象拷贝转化为xlwt对象
    new_worksheet = new_workbook.get_sheet(0)  # 获取转化后工作簿中的第一个表格

    for j in range(0, len(value)):
        new_worksheet.write(rows_old, j, value[j])  # 追加写入数据,注意是从i+rows_old行开始写入
    new_workbook.save(path)  # 保存工作簿
    global count
    count+=1
    print("xls格式表格追加第"+str(count)+"数据成功!")
if __name__ == '__main__':
    info = [['标题', '详细信息', '总价(万)', '均价(m^2)','联系人','电话'], ]
    write_excel_xls(r'C:\Users\ASUS\Desktop\test_worm\details.xls', 'work1', info)
    get_manypage(2)

说一下爬虫的全部的步骤吧,起始页面url是https://shenzhen.anjuke.com/sale/p1,当然这里的p1代表的是页面可以增加,每页应该是60个信息,初始页面如下图所示,初始页面
在初始页面有每一个详情页的url这里用以下的函数获取。本来打算用redis数据库的这样速度会快很多,但总是报错,就算了。

	r=s.get(url=url,headers=header)

    url_info = re.findall('https:.*?time=\d{1,}',r.text)#获取详情页的url
    url_info_list=[]
    for info in url_info:
        # redis1.rpush('url_list', info)
        url_info_list.append(info)
    print(url_info_list)
函数将url获得到并保存在url_info_list列表中。

详情页的url获得到之后就进行再一次的请求,就可以对数据进行提取了,这里提取了标题,详细信息,均价和总价,联系人,电话几个信息,前五个没什么好说的,直接在详情页用BeautifulSoup提取出来就就好了。

	soup=BeautifulSoup(r.text,'lxml')
    #print(soup)
    house_info=soup.find_all('div',class_='house-title')
    house_details=soup.find_all('div',class_='details-item')
    house_price=soup.find_all('div',class_='pro-price')
    直接提取出来相应的信息就好了
    

最后一个电话信息需是一个xhr类型的请求,需要在在详情页请求一遍才能获得。在这里插入图片描述
在这里插入图片描述
找到这个请求发现请求的url为https://shenzhen.anjuke.com/v3/ajax/broker/phone/?broker_id=3982970&token=00bd244b85e99fa171ad7b429ebd11cc&prop_id=1594723649&prop_city_id=13&house_type=1&captcha=里面有几个参数需要在详情页获取,在这里我只是对这个请求的url做了简单的拼接再对服务器请求一遍获得电话信息。

        if re.findall("im_broker_id = '(\d{4,})'", r.text)[0]:
            broker_id = re.findall("im_broker_id = '(\d{4,})'", r.text)[0]
        else:
            continue
        prop_id1 = re.findall("house_id:'.*?'", r.text)
        prop_id = re.findall("(\d{4,})", prop_id1[0])[0]
        token = re.findall("token: '(.*?)',", r.text)[0]
        prop_city_id = re.findall("prop_city_id: '(\d{1,})',", r.text)[0]
        house_type = re.findall("house_type: '(\d{1,})'", r.text)[0]

        url1 = r'https://shenzhen.anjuke.com/v3/ajax/broker/phone/?'
        base = 'broker_id=' + broker_id + '&token=' + token + '&prop_id=' + prop_id + '&prop_city_id=' + prop_city_id + '&house_type=' + house_type + '&captcha='
        url2 = url1 + base
       # 获取broker_id,token,prop_id,prop_city_id,house_type,等信息,
       然后拼接成一个新的url2,再对其进行请求一次。就可以获得电话信息的json字符串。

做完这戏之后对获得的6个信息进行遍历放入列表中,并将其写入excel中。

    for (info1,info2,info3,info4,info5)in zip(house_info,house_details,house_price,contact_list,phone_list):
    #for i in range(len(phone_list)):
        list_info=[]
        info_href=info1.a.attrs['href']
        #print(type(info1))
        info=info1.text.strip()
        inf=info2.text.strip()
        house_title=info.strip()
        house_detail=inf.strip()
        price=re.findall(r'(\d{2,}.)',info3.text)
        house_price=price[0]
        house_price_averge=price[1]
        print('xxxxxxxxxxxxxxxxxxxxxxx')
        counts+=1
        print(counts)
        list_info.append(house_title)
        list_info.append(house_detail)
        list_info.append(house_price.replace('万',''))
        list_info.append(house_price_averge.replace('元',''))
        list_info.append(info4.strip())
        list_info.append(info5)
	  	
	  	write_one_excel_xls_append(r'C:\Users\ASUS\Desktop\test_worm\details.xls', list_info)
	  	

感觉自己写的代码好乱,但是实在是不想再改了,反正也是自己写着玩的,功能都实现了。优化比自己在重新写一遍还要花费时间。而且自己的水平也就这样在改估计也改的不会太好的。

猜你喜欢

转载自blog.csdn.net/qq_42232193/article/details/88370928