1.用于爬取58上的租房信息,限成都,其他地方的,可以把网址改改;
2.这个爬虫有一点问题,就是没用多线程,因为我用了之后总是会报: 'module' object has no attribute '_strptime'这个奇怪的错误,挣扎了许久,放弃;
如有大神看到这篇帖子,希望可以指点一二,不胜感激,谢谢。
3.我本来打算做成EXE文件的,但是在中文处理方面总是乱码,需要进一步研究;
以下为代码:
#!/usr/bin/python # -*- encoding:utf-8 -*-import requests
from bs4 import BeautifulSoupfrom multiprocessing.dummy import Pool as ThreadPoolimport reimport datetimeimport sys# from datetime import datetimereload(sys) sys.setdefaultencoding('utf-8')#得到soup,因后文通用,直接放这儿就行了def urlBS(url): response=requests.get(url) response.encoding = 'utf-8' soup = BeautifulSoup(response.text,"lxml") return soup#通过交互的方式让搜索人输入想要的房屋条件,不输的话有默认值def get_source_url(): base_url='http://cd.58.com/zufang/' #首先,锁定为整租:/zufang/,然后限定为个人房源:/0/,0为个人,1为经纪人 # real_url='http://cd.58.com/zufang/?isreal=true' try: source_key=input('请按序号输入你想要的房屋来源,1为不限,2为个人房源,3为经纪人(默认为2个人房源):\n') except: source_key=2 source_from={1:'',2:'0/',3:'1/'} # 4:'?isreal=true',4为诚信房源专区' try: price_min=str(input('请输入你期望的价格下限(不输默认为500):\n')) except: price_min='500' try: price_max=str(input('请输入你期望的价格上限(不输默认为1000):\n')) except: price_max='1000' price='minprice='+price_min+'_'+price_max try: room_key=input('请输入你想要的房子间数:0为不限,1为1室,2为2室,3为3室,4为4室,5为4室以上(不输默认为1室):\n') except: room_key=1 room_num={0:'',1:'j1/',2:'j2/',3:'j3/',4:'j4/',5:'j5/'} key_words=raw_input('请输入你想要搜索的其他关键词,如小区名称,地铁位置等(不输默认为空):\n') source_url=base_url+source_from[source_key]+room_num[room_key]+'?'+price+'&key='+key_words # print new_url return source_url# new_url='http://cd.58.com/zufang/0/j1/?minprice=600_800&PGTID=0d300008-0006-6cd9-6ba7-a7672ec996c3&ClickID=3' #找到下一页的地址,因为58的网站很坑,它并没有显示共多少页,所以只能通过爬取他的下一页对应的href来得到下一页的链接#但是,更坑的是,他的页面进去后第一次的下一页按了后和当前页是一样的,所以我就在确定有下一页的情况下,直接用当前页+1得到下一页的urldef get_new_list(source_url): new_url=source_url new_url_list=[new_url] while True: soup=urlBS(new_url) cp=re.compile(r'/pn(.)/') finder=soup.find('a',{ 'class':'next'}) if finder: next_url=finder['href'] now_page=cp.findall(source_url) next_page='http://cd.58.com'+next_url if now_page: now_page=now_page[0] newpage=str(int(now_page)+1) new_page=cp.sub(newpage,next_page) else: now_page='1' newpage='2' new_page='http://cd.58.com'+next_url new_url=new_page else: new_page='' break # else: # print 'dont have next page' # print new_url if len(new_url_list)==1: new_url_list.append(new_url) elif new_page==new_url_list[-1]: break else: new_url_list.append(new_url) # print new_url_list return new_url_list#得到房屋信息页的链接def get_house_url(new_url): soup = urlBS(new_url) href_list=soup.select('div[class="img_list"] a') house_url_list=[] for each in href_list: href=each['href'] #print href house_url_list.append(href) return house_url_list#爬取房屋信息,同时不要那些骗子的信息,以及一个月前更新的信息def house_info(house_url): # house_url='http://cd.58.com/zufang/26364594760504x.shtml?version=A&psid=162154127192148068945806804&entinfo=26364594760504_0' # print house_url soup=urlBS(house_url) try: tel=soup.find('span',{ 'class':'tel-num tel-num-geren pl30 f30'}).text #个人房源 except: tel=soup.find('span',{ 'class':'tel-num pl30 f30'}).text #中介 match_tel=re.search(r'^1\d{5}.*',tel) #排除所有电话号码以0开始的人,即留固定电话的人,因为我们认为,固定房源的人是不会留固定电话的 situation=soup.find('div',{ 'class':'description-content'}).text.strip() # print situation match_si=re.search(u'(我是房东|男士勿扰|男生勿扰|限女生|微信|男士|男性|男生|女性|女的|姐妹|"+")',situation) #更新时间 update_time=soup.find('span',{ 'class':'pl10'}).text update_date = datetime.datetime.strptime(update_time.replace('更新时间:',''), "%Y-%m-%d").date() thirtyDayAgo=datetime.date.today() + datetime.timedelta(days=-30) day_line=(update_date - thirtyDayAgo).days if not match_tel: #认为隐藏了电话号码的,电话号码以0开始的,都是骗子,不要他 # print '电话号码有问题,骗子' pass elif match_si: #认为含有某些字的全部为骗子,把这些排除掉 # print '内容有问题,骗子' pass elif day_line<0: #取近30天更新的数据,时间太长了的数据没啥意义 # print '已经是一个月之前的消息了' pass else: print house_url print situation print tel #标题 title=soup.find('h1',{ 'class':'main-title font-heiti'}).text print title #价格 p=re.compile(r'\n|\t|\r| ') rent_price=soup.find('i',{ 'class':'ncolor'}).text price=p.sub('',rent_price) print price #房屋大小 house=soup.find_all('li',{ 'class':'house-primary-content-li clearfix'}) house_content=p.sub('',house[0].text) print house_content #小区 try: house_Community=p.sub('',house[1].text) except: house_Community='' print house_Community #位置 try: house_place=p.sub('',house[2].text) except: house_place='' print house_place #设施 try: facility=soup.find('li',{ 'class':'house-primary-content-li clearfix person-config'}) facility=p.sub('',facility.text) except: facility='' print facility #联系人 contact=soup.find('li',{ 'class':'house-primary-content-li clearfix person-contact'}).text contact=p.sub('',contact) print contact print update_time+'\n\n\n' # a=[house_url,price,house_content,house_Community,house_place,title,situation,facility] f.write('----------------------------------------------------------------------------------\n') f.write(house_url+'\n'+price+'\n'+house_content+'\n'+house_Community+'\n'+house_place+'\n'+title+'\n'+situation+'\n'+facility+'\n\n')if __name__=='__main__': source_url=get_source_url() print source_url # source_url='http://cd.58.com/zufang/0/?minprice=500_1500&key=四河' get_new_list=get_new_list(source_url) # print get_new_list f=open("house_rent.txt", "w") #先清空,然后再打开,再写入,写入时的方式是a(追加) # f.truncate() # f.close() # # f=open("house_rent.text", "a") print '正在下载,请稍候。。。\n\n' # pool = ThreadPool(4) for new_url in get_new_list: new_url=new_url.encode('utf-8').decode('utf-8') # print new_url house_url_list=get_house_url(new_url) # print house_url_list for each in house_url_list: #本来打算使用多线程,但是总是会报: 'module' object has no attribute '_strptime'这个奇怪的错误,挣扎了许久,放弃 house_info(each) # results = pool.map(house_info, house_url_list) # pool.close() # pool.join() f.close()