如何高效地爬取链家的房源信息(四)
“Python實現的鏈家網站的爬蟲第四部分,最后一部分。”
本系列文將以鏈家南京站為例,使用Python實現鏈家二手房源信息的爬蟲,將數據爬取,并存入數據庫中,以便使用。
本系列第一部分為基礎:
如何高效地爬取鏈家的房源信息(一)
本系列第二部分為爬取小區信息:
如何高效地爬取鏈家的房源信息(二)
本系列第三部分為爬取在售二手房信息:
如何高效地爬取鏈家的房源信息(三)
本文是第四部分,爬取歷史成交二手房信息并存入數據庫,部分代碼依賴于第一部分,同時依賴于第二部分的結果。
在前文中已經獲取了小區信息,并存在了數據庫中,直接讀庫遍歷小區進行爬取:
def do_xiaoqu_chengjiao_spider(db_xq,db_cj):
? ? """
? ? 批量爬取小區成交記錄
? ? """
? ? count=0
? ? xq_list=db_xq.fetchall()
? ? for xq in xq_list:
? ? ? ? xiaoqu_chengjiao_spider(db_cj,xq[0],xq[1])
? ? ? ? count+=1
? ? ? ? print ('have spidered %d xiaoqu %s' % (count,xq[0]))
? ? print( 'done')
對某一個小區內的所有成交房源進行爬取,需要分頁:
def xiaoqu_chengjiao_spider(db_cj, xq_url=u"https://nj.lianjia.com/xiaoqu/1411000000391/", xq_name=u"default"):
? ? """
? ? 爬取小區成交記錄
? ? """
? ? url = xq_url.replace('xiaoqu/','chengjiao/c');
? ? try:
? ? ? ? req = urllib.request.Request(url, headers=hds[random.randint(0, len(hds) - 1)])
? ? ? ? source_code = urllib.request.urlopen(req, timeout=10).read()
? ? ? ? plain_text = source_code.decode('utf-8');
? ? ? ? soup = BeautifulSoup(plain_text,"html.parser")
? ? except (urllib.request.HTTPError, urllib.request.URLError) as e:
? ? ? ? print(e)
? ? ? ? exception_write('xiaoqu_chengjiao_spider', xq_url)
? ? ? ? return
? ? except Exception as e:
? ? ? ? print(e)
? ? ? ? exception_write('xiaoqu_chengjiao_spider', xq_url)
? ? ? ? return
? ? content = soup.find('div', {'class': 'page-box house-lst-page-box'})
? ? total_pages = 0
? ? if content:
? ? ? ? d = "d=" + content.get('page-data')
? ? ? ? loc = {}
? ? ? ? glb = {}
? ? ? ? exec(d, glb, loc);
? ? ? ? total_pages = loc['d']['totalPage']
? ? print(u"xiaoqu %s chengjiao totalpage %d" % (xq_name,total_pages));
? ? threads = []
? ? for i in range(total_pages):
? ? ? ? tmp= u'chengjiao/pg%dc'% (i + 1)
? ? ? ? url_page = url.replace('chengjiao/c',tmp);
? ? ? ? t = threading.Thread(target=chengjiao_spider, args=(db_cj, url_page))
? ? ? ? threads.append(t)
? ? for t in threads:
? ? ? ? t.start()
? ? for t in threads:
? ? ? ? t.join()
爬取單個頁面內的成交記錄信息:
def chengjiao_spider(db_cj, url_page=u"https://nj.lianjia.com/chengjiao/pg4c1411000000142/"):
? ? """
? ? 爬取頁面鏈接中的成交記錄
? ? """
? ? print(u"爬取頁面%s成交記錄" % url_page);
? ? try:
? ? ? ? req = urllib.request.Request(url_page, headers=hds[random.randint(0, len(hds) - 1)])
? ? ? ? source_code = urllib.request.urlopen(req, timeout=10).read()
? ? ? ? plain_text = source_code.decode('utf-8');
? ? ? ? soup = BeautifulSoup(plain_text,"html.parser")
? ? except (urllib.request.HTTPError, urllib.request.URLError) as e:
? ? ? ? print(e)
? ? ? ? exception_write('chengjiao_spider', url_page)
? ? ? ? return
? ? except Exception as e:
? ? ? ? print(e)
? ? ? ? exception_write('chengjiao_spider', url_page)
? ? ? ? return
? ? recodenum = 0;
? ? cjs = soup.find('ul', {'class': 'listContent'});
? ? cj_list = cjs.findAll('li', {})
? ? for cj in cj_list:
? ? ? ? info_dict = {}
? ? ? ? title = cj.find('div', {'class': 'title'});
? ? ? ? houseInfo = cj.find('div', {'class': 'houseInfo'});
? ? ? ? dealDate = cj.find('div', {'class': 'dealDate'});
? ? ? ? totalPrice = cj.find('div', {'class': 'totalPrice'});
? ? ? ? positionInfo = cj.find('div', {'class': 'positionInfo'});
? ? ? ? source = cj.find('div', {'class': 'source'});
? ? ? ? unitPrice = cj.find('div', {'class': 'unitPrice'});
? ? ? ? dealHouseInfo = cj.find('div', {'class': 'dealHouseInfo'});
? ? ? ? dealCycleeInfo = cj.find('div', {'class': 'dealCycleeInfo'});
? ? ? ? href = title.find('a')
? ? ? ? if not href:
? ? ? ? ? ? continue
? ? ? ? info_dict.update({u'鏈接': href.attrs['href']})
? ? ? ? content = title.text.split()
? ? ? ? if content:
? ? ? ? ? ? info_dict.update({u'小區名稱': content[0]})
? ? ? ? ? ? info_dict.update({u'戶型': content[1]})
? ? ? ? ? ? info_dict.update({u'面積': content[2]})
? ? ? ? content = houseInfo.text.split('|') #unicode(cj.find('div', {'class': 'con'}).renderContents().strip())
? ? ? ? if content:
? ? ? ? ? ? info_dict.update({u'朝向': content[0].strip()})
? ? ? ? ? ? if len(content) >= 2:
? ? ? ? ? ? ? ? info_dict.update({u'裝修': content[1].strip()})
? ? ? ? ? ? if len(content) >= 3:
? ? ? ? ? ? ? ? info_dict.update({u'電梯': content[2].strip()})
? ? ? ? info_dict.update({u'簽約時間': dealDate.text})
? ? ? ? info_dict.update({u'簽約總價': totalPrice.text}) #注意值
? ? ? ? content = positionInfo.text.split()
? ? ? ? if len(content) >= 2:
? ? ? ? ? ? info_dict.update({u'樓層': content[0].strip()})?
? ? ? ? ? ? info_dict.update({u'年代樓型': content[1].strip()})??
? ? ? ? else:
? ? ? ? ? ? info_dict.update({u'樓層': content[0].strip()})??
? ? ? ? info_dict.update({u'來源': source.text})
? ? ? ? info_dict.update({u'簽約單價': unitPrice.text}) #可能為*
? ? ? ? #content = dealHouseInfo.text.split()
? ? ? ? if dealHouseInfo != None:
? ? ? ? ? ? for span in dealHouseInfo.find('span', {'class': 'dealHouseTxt'}).findAll('span'):
? ? ? ? ? ? ? ? if span.text.find(u'房屋') != -1:
? ? ? ? ? ? ? ? ? ? info_dict.update({u'稅費': span.text})? # 滿幾年
? ? ? ? ? ? ? ? elif span.text.find(u'距') != -1:
? ? ? ? ? ? ? ? ? ? info_dict.update({u'地鐵': span.text})
? ? ? ? #content = dealCycleeInfo.text.split()
? ? ? ? if dealCycleeInfo != None:
? ? ? ? ? ? for span in dealCycleeInfo.find('span',{'class': 'dealCycleTxt'}).findAll('span'):
? ? ? ? ? ? ? ? if span.text.find(u'掛牌') != -1:
? ? ? ? ? ? ? ? ? ? info_dict.update({u'掛牌價': span.text})
? ? ? ? ? ? ? ? elif span.text.find(u'成交周期') != -1:
? ? ? ? ? ? ? ? ? ? info_dict.update({u'成交周期': span.text})
? ? ? ? command = gen_chengjiao_insert_command(info_dict)
? ? ? ? db_cj.execute(command, 1)
? ? ? ? recodenum += 1;
? ? print(u"爬取頁面%s成交記錄%d條" % (url_page,recodenum));
爬取的成交記錄信息將被存儲到數據庫表中。
整個爬取過程還是很快的,在爬取完小區、在售、成交三類信息之后,就可以拿這些數據去進行想要做的分析了。
長按進行關注。
總結
以上是生活随笔為你收集整理的如何高效地爬取链家的房源信息(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何高效地爬取链家的房源信息(三)
- 下一篇: MIME格式解析