爬蟲學習之路(二)
阿新 • • 發佈:2019-02-13
這次的爬蟲程式,依然沒有用框架。。
目標是爬取房天下新房和二手房網頁中的房屋資訊,如地址、面積、單價、座標等,鑑於新手房前端頁面比較混亂(我發現的頁面就有三種,相應的寫了三套方案),我的程式碼寫的也就比較混亂,所以接下來我只記錄二手房的爬取過程及程式碼。
房天下二手房的頁面如下,上面是選擇條件,下面是房源列表
房源列表中最多隻能顯示100頁,其他的會被捨棄,也就是說,如果要得到完整的資料,我們要確保房屋列表中的房子不多於100頁。我採取的方法是點進區域最小的分類,然後遍歷每個區域。
我的爬蟲的爬取路徑概括起來說就是:進入區頁面(鼓樓)-->爬取到區下一級分類的頁面連結列表(北京西路等頁面的連結)-->進入二級分類頁面(北京西路等)-->爬取房屋列表中每個房子詳細頁面的連結-->進入詳細頁面爬取地址單價等資訊
思路講完了,貼程式碼
fangtx_ershou.py
detail.pyimport requests from bs4 import BeautifulSoup from lxml import etree import time import os,sys from detail import get_page_detail import pymysql #網頁的請求頭 header={ 'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36' } def get_erji_url(url): response=requests.get(url,headers=header) if response.status_code==200: soup=BeautifulSoup(response.text,'lxml') sel=etree.HTML(response.text) #獲取區下一級分類的url列表 erji_url_list=sel.xpath('//p[@id="shangQuancontain"]/a/@href') print(erji_url_list) #for erji_url in erji_url_list: for index in range(1,len(erji_url_list)): time.sleep(0.5) print(erji_url_list[index],"\n\n") houzhui=str(erji_url_list[index]) url="http://esf.nanjing.fang.com"+houzhui print(url,'\n\n') get_info(url) def get_info(url): response=requests.get(url,headers=header) #通過BeautifulSoup進行解析出每個房源詳細列表並進行列印 soup=BeautifulSoup(response.text,'lxml') #此列表中包括每個房屋欄的所有資訊 result_li=soup.find_all('dl',{'class':'list rel'}) #連線database conn=pymysql.connect(host="",port=3306,user="",password="",database="",charset="utf8") #得到一個可以執行SQL語句的游標物件 cursor=conn.cursor() #將當前網頁抓到的連結寫入檔案,with語句會自動close()已開啟檔案 with open(r"F:\python\python_code\files\fang_url.txt","w") as file: #從房源列表中獲取有用的連結等資訊 for i in result_li: try: time.sleep(0.2) page_url=str(i) #通過xpath獲取房屋連結和地址 sel=etree.HTML(page_url) result_href=sel.xpath('//dd/p[@class="title"]/a/@href')[0] loupan_address=sel.xpath('//dd/p[@class="mt10"]/span/@title')[0] print("房子連結:"+"http://esf.nanjing.fang.com/"+result_href) print("房子地址:"+loupan_address) file.write("http://esf.nanjing.fang.com/"+result_href+'\n\n') #詳細頁面的函式呼叫 [loupan_name,wuye_type,price,building_type,house_type,x,y,pic_url,region,area,district]=get_page_detail("http://esf.nanjing.fang.com/"+result_href) print(loupan_name,loupan_address,wuye_type,price,building_type,house_type,x,y,pic_url,region,area,district) print('\n\n') except: continue #入庫 #定義要執行的sql語句 sql="INSERT IGNORE INTO tb_loupan_detail_ershou(loupan_name,loupan_address,wuye_type,price,building_type,house_type,jingdu,weidu,pic_url,region,area,district) VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s);" try: #執行SQL語句 cursor.execute(sql,[loupan_name,loupan_address,wuye_type,price,building_type,house_type,x,y,pic_url,region,area,district]) #提交事務 conn.commit() except Exception as e: #有異常,回滾事務 #conn.rollback() continue #關閉游標物件 cursor.close() #關閉資料庫連線 conn.close() #進行下一頁的爬取 result_next_page=soup.find('a',{'id':'PageControl1_hlk_next'}) print(soup.find('a',{'id':'PageControl1_hlk_next'}),"\n\n") if result_next_page: aaaaaaa=0 #函式進行遞迴 get_info('http://esf.nanjing.fang.com/'+result_next_page.attrs['href']) else: print('沒有下一頁了') if __name__ == '__main__': qu_list=['/house-a0265/','/house-a0268/','/house-a0270/','/house-a0264/','/house-a0267/','/house-a0271/','/house-a0272/','/house-a0263/','/house-a0269/','/house-a0274/','/house-a0275/','/house-a013046/'] region_list=['鼓樓','江寧','浦口','玄武','建鄴','棲霞','雨花','秦淮','六合','溧水','高淳','南京周邊'] #更改至f盤相應路徑下 path="f:/ershoufang" os.chdir(path) '''獲得當前路徑 ''' cwd=os.getcwd() print(cwd) file_list=os.listdir() print(file_list) print("\n") for i in qu_list: url='http://esf.nanjing.fang.com'+i print(url) index=qu_list.index(i) region=region_list[index] print(region) #try: file_name=i.replace("/","")+".txt" print(file_name) if file_name in file_list: print("抓取開始") get_erji_url(url) os.remove(file_name) #except: #continue
import requests from bs4 import BeautifulSoup from lxml import etree import re #網頁的請求頭 header={ 'user-agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36' } def get_page_detail(url): response=requests.get(url,headers=header) if response.status_code==200: soup=BeautifulSoup(response.text,'lxml') sel=etree.HTML(response.text) #獲取詳細資訊 loupan_name=sel.xpath('//*[@id="agantesfxq_C03_05"]/text()') if len(loupan_name): loupan_name=loupan_name[0] #print(loupan_name) wuye_type=sel.xpath('//div[@class="w1200 clearfix"]/div[1]/div[1]/div[2]/div[4]/span[2]/text()') if len(wuye_type): wuye_type=wuye_type[0].strip() #print(wuye_type) price=sel.xpath('//div[@class="trl-item1 w132"]/div[@class="tt"]/text()') if len(price): price=price[0].strip() #print(price) building_type="二手房" #print(building_type) house_type=sel.xpath('//div[@class="trl-item1 w146"]/div[@class="tt"]/text()') if len(house_type): house_type=house_type[0].replace("\r", "").replace("\n", "").replace("\t", "").strip() #print(house_type) map=sel.xpath('//div[@class="zf_new_left floatl"]/script/text()')[0] patx = 'pageConfig.x=\'(.*?)\';' x=re.findall(patx,str(map),re.S)[0] paty='pageConfig.y=\'(.*?)\';' y=re.findall(paty,str(map),re.S)[0] #print(x) #print(y) pic_url=sel.xpath('//*[@id="bigImgBox"]/div[1]/img/@src') if len(pic_url): pic_url=pic_url[0] #print(pic_url) diqu=sel.xpath('//*[@id="address"]/a/text()') if len(diqu): region=diqu[0].strip() district=diqu[1].strip() area=sel.xpath('//div[@class="trl-item1 w182"]/div[@class="tt"]/text()') if len(area): area=area[0] #print(area) return loupan_name,wuye_type,price,building_type,house_type,x,y,pic_url,region,area,district if __name__ == '__main__': # url連結 url = 'http://esf.nanjing.fang.com/chushou/3_165137745.htm' # 頁面爬取函式呼叫 get_page_detail(url)
爬太快的話會被網站禁ip,所以每爬一條需要休眠0.2秒,速度很慢