这次的爬虫程序,依然没有用框架。。
目标是爬取房天下新房和二手房网页中的房屋信息,如地址、面积、单价、坐标等,鉴于新手房前端页面比较混乱(我发现的页面就有三种,相应的写了三套方案),我的代码写的也就比较混乱,所以接下来我只记录二手房的爬取过程及代码。
房天下二手房的页面如下,上面是选择条件,下面是房源列表
房源列表中最多只能显示100页,其他的会被舍弃,也就是说,如果要得到完整的数据,我们要确保房屋列表中的房子不多于100页。我采取的方法是点进区域最小的分类,然后遍历每个区域。
我的爬虫的爬取路径概括起来说就是:进入区页面(鼓楼)-->爬取到区下一级分类的页面链接列表(北京西路等页面的链接)-->进入二级分类页面(北京西路等)-->爬取房屋列表中每个房子详细页面的链接-->进入详细页面爬取地址单价等信息
思路讲完了,贴代码
fangtx_ershou.py
import 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)