爬蟲實戰(zhàn)1-----鏈家二手房信息爬取

經(jīng)過一段機器學習之后,發(fā)現(xiàn)實在是太枯燥了,為了增添一些趣味性以及熟練爬蟲,在之后會不定時的爬取一些網(wǎng)站

  • 旨在熟悉網(wǎng)頁結(jié)構--尤其是HTML的元素,ajax存儲,json;熟練使用pyspider,scrapy兩大框架;掌握基本的requests庫,re正則匹配,urllib庫,Beautifulsoup,css,pyquery 選擇器的使用,pandas庫的輔助;mongodb,csv,xlsx的存儲,redis分布式爬蟲;簡單的反爬技巧

本篇作為實戰(zhàn)的第一篇,爬取了鏈家二手房的信息,一些思路借鑒了網(wǎng)上的框架結(jié)構,并非純粹原創(chuàng),特此聲明,站在巨人的肩膀上眺望

該篇我自己實踐學習到的、需要注意的內(nèi)容如下

本項目實例的知識點有
1. format 和 迭代yield 的使用

2. 三大解析工具的使用   XPath,  beautifulsoup,pquery   

3.關于變簽選取,beautifulsoup 的select 方法返回的是列表,需要格外注意, 且用select 來選擇class 標簽的時候,只取 空格前邊,class 等號后邊的,比如62行


4.如何將字典信息轉(zhuǎn)化為pd.DataFrame 
比如,dict={'a':'1','b':'2','c':'3'}
直接使用data=pd.DataFrame(dict)則會報錯:ValueError: If using all scalar values, you must pass an index
如何解決呢?比較好的方法介紹兩種
第一種為:data=pd.DataFrame(dict,index=[0])
第二種為:pd.DataFrame(list(idct.items())    代碼位置117行



5.當有多個列表同時需要轉(zhuǎn)化為dataframe 的時候,可以將所有的字典全部的存放到一個列表當中,隨后直接用pd.dataframe 

所對應的代碼和注釋如下:

class  lianjiaspider(object):
    def __init__(self):
        self.home_url='http://bj.lianjia.com/'#鏈家首頁的鏈接
        self.auth_url='https://passport.lianjia.com/cas/login?service=http%3A%2F%2Fbj.lianjia.com%2F'#用戶的登陸界面,登陸后為鏈家首頁的界面
        self.zaishou_url='https://su.lianjia.com/ershoufang/pg{}/'
        self.headers=headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.8',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Host': 'su.lianjia.com',
    'Referer': 'https://su.lianjia.com/chengjiao/',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36',
    'Upgrade-Insecure-Requests': '1',
    'X-Requested-With': 'XMLHttpRequest',

}


    def main_url(self,page):#生成在售房屋每一頁的URL
        #r=requests.get(self.home_url)
        #return r.text
        for next_page in range(1,int(page)):
            yield self.zaishou_url.format(next_page)#,可以用于迭代

    def detail_sall_url(self):
        user_num = input('請輸入你想要的主頁的頁數(shù):')
        detail_url_list = []
        for i in self.main_url(str(int(user_num)+1)):
            try:
                response=requests.get(i,headers=self.headers)
                if response.status_code==200:#一定不能加引號啊,不然怎么都匹配不到的
                    html=response.text
                    soup=bp(html,'lxml')
                    detail_a_label=soup.select('.clear .noresultRecommend')#返回的是一個列表
                    for each_a_label in detail_a_label:
                        detail_url_list.append(each_a_label['href'])#獲得標簽,然后獲取屬性href ,并依次取出詳情頁的標簽把他放在一個列表當中
            except requests.ConnectionError as e:
                print ('error:', e.args)
        return detail_url_list


    def parse_detail_url(self,detail_url_list):#用于解析詳情頁
        info_concat=[]
        for each_detail_url in detail_url_list:
            response_detail=requests.get(each_detail_url)
            if response_detail.status_code==200:
                html_detail_url=response_detail.text
                info={}#存為字典/json 形式
                soup=bp(html_detail_url,'lxml')
                info1=soup.select('.title .main')#獲取含有標題的標簽的列表
                for  j in  info1:
                    info['出售房屋標題']=j.get_text()#獲取標題
                info2=soup.select('.price .total')#獲取房屋價格
                for p in info2:
                    info['總價']=p.string + '萬'
                info3 = soup.select('.unitPriceValue')  # 獲取房屋每平方均價
                for unit_price in info3:
                    info['平方售價'] = unit_price.get_text()
                info4 = soup.select('.room')  # 獲取廳室
                for property in info4:
                    info['房屋屬性'] = property.get_text()
                info5 = soup.select('.area')
                for areas in info5:
                    info['面積'] = areas.get_text()
                info6 = soup.select('.type')
                for areas in info6:
                    info['朝向'] = areas.get_text()
                    info_concat.append(info)
            else:
                print ('error:', requests.ConnectionError)
        return info_concat


    def save_to_xlsx(self,detail_url_list): #用于將數(shù)據(jù)存儲到 excel 當中
        pd.DataFrame(self.parse_detail_url(detail_url_list)).to_excel('鏈家二手房.xlsx', sheet_name='鏈家二手房信息')






def main():
    lianjia=lianjiaspider()#實例化
    detail_url_list=lianjia.detail_sall_url()
    lianjia.save_to_xlsx(detail_url_list)


if __name__=='__main__':
    main()

代碼選取5頁的內(nèi)容爬取并存儲結(jié)果如下

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,023評論 25 709
  • 1 前言 作為一名合格的數(shù)據(jù)分析師,其完整的技術知識體系必須貫穿數(shù)據(jù)獲取、數(shù)據(jù)存儲、數(shù)據(jù)提取、數(shù)據(jù)分析、數(shù)據(jù)挖掘、...
    whenif閱讀 18,313評論 45 523
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,987評論 2 59
  • 余生冗長孤寂量, 卻把佳人思難忘。 渡人渡已兩難渡, 最是情字逾釋然。
    瓶蓋飛機頭閱讀 193評論 0 0
  • 陌生人,祝你安好。謝謝閱讀。 如果我走在鋪滿落葉的小路 風應該會知道我很想你 一片片的落葉不肯離去 所以和風纏綿 ...
    一只無雙呀閱讀 418評論 3 2

友情鏈接更多精彩內(nèi)容