这几天一直在学习如何用python写爬虫,来写个小爬虫来验证一下学习效果吧。本文适合新手,欢迎大家欣赏~提示:本文仅供学习交流,请勿用于非法用途!!!1、网页分析从客客网抓取石家庄二手房信息,先打开链接https://sjz.ke.com/ershoufang/。在不添加过滤器的情况下,总共找到了42817个房屋。我们点击第二个页面,然后查看链接就变成了https://sjz.ke.com/ershoufang/pg2/。因此,可以发现/pg{i},i是页码。算上拉条君体育老师教的数学,每页30页,最多可以选100页。所以最多可以爬取3000个属性,和上面给的40000个还是有差距的,所以尝试人为改变pg{i}中的i,回车请求。https://sjz.ke.com/ershoufang/pg200/https://sjz.ke.com/ershoufang/pg300/发现这两个请求返回相同的房产信息数据。都是100页的信息,所以得出结论。通过客客网网页端,您可以查看特定条件下的房产信息,最多可查看3000个房产。害,最多只能买3000套,有钱不花的感觉真的很不爽~逃避:)~~所以,我们加一些条件,比如只能5个以上,2个房间。请求~发现链接变成了https://sjz.ke.com/ershoufang/pg2mw1l2/。mw1l2应该过滤条件。看到只有2399套,Oak,还是爬上去吧。2.撸起袖子写代码麻雀虽小五脏俱全,但是这个爬虫设计分为三个部分,爬取、解析、存储。爬虫爬虫使用的是requests库,比python自带的库urllib好用多了。importrequestsdefget_a_page(url):result=requests.get(url)print(result.text)if__name__=='__main__':foriinrange(1,101):get_a_page(f'https://sjz.ke.com/ershoufang/pg{i}mw1l2/')for循环打印返回数据,发现没有问题。其实循环i到81就好了,毕竟我们知道只有不到2400套。ParsingParsing使用的是pyquery,一个在使用上类似于Jquery的库。完整的API,https://pythonhosted.org/pyquery/api.html。还有一个解析库`bs4,下次试试。发现如图所示读取ul中的一个div可以得到我们想要的数据。importrequestsfrompyqueryimportPyQueryaspqiimportjsondefget_a_page(url):result=requests.get(url)doc=pq(result.text)ul=doc('.sellListContent')divs=ul.children('.clear.info.clear').items()fordivindiv:count+=1title=div.children('.titlea').text()place=div.children('.address.flood.positionInfoa').text()msg=div.children('.address.houseInfo').text()price=div.children('.address.priceInfo.totalPricespan').text()per_meter=div.children('.address.priceInfo.unitPrice').attr('data-price')dict={'title':title,'place':place,'msg':msg,'price':price,'per_meter':per_meter}print(str(count)+':'+json.dumps(dict,ensure_ascii=False))代码如上,pyquery的children方法是找子标签,find方法是找后代标签。这里我们只需要找到下一代。然后通过text查找label中包含的文字。attr是获取属性内容,因为per_meter从属性中获取比较简单,tag中的内容也包括“元/平方米”。保存这次我们直接保存为csv,一种类似excel的文件格式。使用熊猫库。完整代码如下:importrequestsfrompyqueryimportPyQueryaspqimportjsonimportpandasaspdcolumns=['title','msg','price','per_meter']#下载某网页defget_a_page(url):result=requests.get(url)doc=pq(result.text)ul=doc('.sellListContent')divs=ul.children('.clear.info.clear').items()count=0titles=[]places=[]msgs=[]prices=[]per_meters=[]fordivindiv:count+=1title=div.children('.titlea').text()place=div.children('.address.flood.positionInfoa').text()msg??=div.children('.address.houseInfo').text()price=div.children('.address.priceInfo.totalPricespan').text()per_meter=div.children('.address.priceInfo.unitPrice').attr('data-price')dict={'title':title,'place':place,'msg':msg,'price':price,'per_meter':per_meter}标题.追加(标题)places.append(place)msg??s.append(msg)prices.append(price)per_meters.append(per_meter)print(str(count)+':'+json.dumps(dict,ensure_ascii=False))数据={'title':标题,'place':地方,'msg':msgs,'price':价格,'per_meter':per_meters}df=pd.DataFrame(数据=数据,列=列)df.to_csv('sjz。csv',mode='a',index=False,header=False)if__name__=='__main__':foriinrange(1,101):get_a_page(f'https://sjz.ke.com/ershoufang/pg{i}mw1l2/')multi-process因为get_a_page函数需要运行100次,有点慢,所以使用multi-process加速,这部分代码请直接copy改main从multiprocessing.poolimportPoolif__name__=='__main__':pool=Pool(5)group=([f'https://sjz.ke.com/ershoufang/pg{x}mw1l2/'forxinrange(1,101)])pool.map(get_a_page,group)pool.close()pool.join()3、最后查看效果:效果还不错。有人会说,为什么不拆分msg信息,将楼层、房厅、建筑年份等分开存放。一开始,我这样做了,但我发现不需要msg数据项。有的房主不填楼龄、楼层等,就全部拿过来。辣条君的第一个爬虫到此结束。虽然简单,但是写完之后还是有一点小满足的。以后会继续学习爬虫,写一些博客。小伙伴们点个赞就走吧~
