大家好,我是杯酒先生。这是我第一次写这种分享项目的文章。可能比较水,不够全面。而且肯定有错误的地方,希望大家在评论中指点指点,不胜感激!程序或脚本。其他不太常用的名称包括ant、autoindex、emulator或worm。------百度百科说爬虫是用来定时获取海量数据,然后进行处理和使用的。是大数据、金融、机器学习等必备的支撑条件之一。目前在一线城市,爬虫的薪资比较客观,后期晋升为中高级爬虫工程师、数据分析师、大数据开发岗位等,都是不错的转行。2.项目目标这里介绍的项目不需要太复杂。最终目的是将帖子的每一条评论都抓取到数据库中,并使得数据更新成为可能,防止重复抓取和反抓取等措施。3、项目准备这部分主要介绍本文需要的工具、涉及到的库、网页等资料及其他软件:PyCharm需要的库:Scrapy、selenium、pymongo、user_agent、datetime目标网站:http://bbs.foodmate.net插件:chromedriver(版本一定要正确)四、项目分析1、确定爬取网站的结构简而言之:确定网站的加载方式,如何进入帖子逐级爬取数据,用什么格式保存数据等。其次,观察网站的层级结构,也就是说,如何按版块一点点进入post页面,这对于这个爬虫任务来说很重要,也是写代码的主要部分。2、如何选择合适的数据爬取方式?我知道的爬取方法有以下几种(不全,但是比较常用):1)请求框架:使用这个http库可以灵活的爬取需要的数据,简单但是处理起来有点繁琐,可以配合抓包工具使用获取数据。但是需要确定headers和对应的请求参数,否则无法获取到数据;很多app爬取,图片视频爬取可以随时爬取和停止,相对轻量灵活,高并发和分布式部署也很灵活,可以更加功能化。很好的实现。2)scrapy框架:scrapy框架可以说是爬虫最常用也是最好用的爬虫框架。它有很多优点:scrapy是异步的;使用更具可读性的xpath代替正则表达式;强大的统计和日志系统;同时爬取不同的url;支持shell模式,方便独立调试;支持编写中间件,方便编写一些统一的过滤器;可以通过管道等方式存入数据库,这也是本文要介绍的框架(结合selenium库)。五、项目实现1.第一步:确定网站类型首先解释一下是什么意思,看什么网站,首先要看网站的加载方式,是静态加载还是动态加载(js加载)或其他方法;根据不同的加载方式需要不同的处理方式。然后我们观察今天爬的网站,发现是一个很有年代感的论坛。我们首先猜测这是一个静态加载的网站;我们开启了组织js加载的插件,如下图。刷新后,发现确实是一个静态网站(如果能正常加载,基本就是静态加载了)。2、第二步:确定层次关系其次,我们今天要爬取的网站是美食论坛网站,是一个静态加载的网站。前面分析的时候我们已经了解过了,然后是层级结构:大概就是上面的流程,一共有三个层级递进访问,然后就到了发帖页面,如下图。部分代码展示:一级接口:defparse(self,response):self.logger.info("进入网页!")self.logger.info("获取论坛列表!")column_path_list=response.css('#ct>div.mn>div:nth-child(2)>div')[:-1]forcolumn_pathincolumn_path_list:col_paths=column_path.css('div>table>tbody>tr>td>div>a')。xpath('@href').extract()forpathincol_paths:block_url=response.urljoin(path)yieldscrapy.Request(url=block_url,callback=self.get_next_path,)辅助接口:defget_next_path(self,response):self.logger。info("进入论坛!")self.logger.info("获取文章列表!")ifresponse.url=='http://www.foodmate.net/know/':passelse:try:nums=response.css('#fd_page_bottom>div>label>span::text').extract_first().split('')[-2]except:nums=1fornuminrange(1,int(nums)+1):tbody_list=响应。css('#threadlisttableid>tbody')fortbodyintbody_list:if'normalthread'instr(tbody):item=LunTanItem()item['article_url']=response.urljoin(tbody.css('*>tr>th>a.s.xst').xpath('@href').分机ract_first())item['type']=response.css('#ct>div>div.bm.bml.pbn>div.bm_h.cl>h1>a::text').extract_first()item['title']=tbody.css('*>tr>th>a.s.xst::text').extract_first()item['spider_type']="论坛"item['source']="食品论坛"ifitem['article_url']!='http://bbs.foodmate.net/':yieldscrapy.Request(url=item['article_url'],callback=self.get_data,meta={'item':item,'content_info':[]})try:callback_url=response.css('#fd_page_bottom>div>a.nxt').xpath('@href').extract_first()callback_url=response.urljoin(callback_url)yieldscrapy.Request(url=callback_url,callback=self.get_next_path,)exceptIndexError:pass三级界面:defget_data(self,response):self.logger.info("正在刷取论坛数据!")item=response.meta['item']content_list=[]divs=response.xpath('//*[@id="postlist"]/div')user_name=response.css('div>div.pi>div:nth-child(1)>a::text').extract()publish_time=response.css('div.authi>em::text').extract()floor=divs.css('*strong>a>em::text').extract()s_id=divs.xpath('@id').extract()foriinrange(len(divs)-1):content=''尝试:strong=response.css('#postmessage_'+s_id[i].split('_')[-1]+'').xpath('string(.)').extract()forsinstrong:content+=s.split(';')[-1].lstrip('\r\n')datas=dict(content=content,#内容reply_id=0,#回复的楼层,默认0user_name=user_name[i],#?户名publish_time=publish_time[i].split('于')[-1],#%Y-%m-%d%H:%M:%S'id='#'+floor[i],#楼)content_list.append(datas)exceptIndexError:passitem['content_info']=response.meta['content_info']item['scrawl_time']=datetime.now().strftime('%Y-%m-%d%H:%M:%S')item['content_info']+=content_listdata_url=response.css('#ct>div.pgbtn>a').xpath('@href').extract_first()ifdata_url!=None:data_url=response.urljoin(data_url)yieldscrapy.Request(url=data_url,callback=self.get_data,meta={'item':item,'content_info':item['content_info']})else:item['scrawl_time']=datetime.now().strftime('%Y-%m-%d%H:%M:%S')self.logger.info("正在存储!")print('成功存储')yielditem3.第三步:确定爬取方式由于是静态网页,所以首先决定使用scrapy框架直接获取数据,通过初步测试,发现采用的方式是确实可行,但那时候年少轻狂,低估了网站。保护措施,由于本人耐心有限,没有加定时器限制爬取速度,导致被网站限制,网站由静态加载网页变为:动态加载网页后验证算法和然后进入网页,直接访问会被屏蔽。后台拒绝,可是怎么会出现这种问题呢?我真聪明。简单思考后(1天),我将解决方案改为scrapy框架+selenium库的方法,通过调用chromedriver模拟访问网站,加载网站后进行爬取。拿不下就完了,事实证明,这种方法确实可行且高效。代码的实现部分如下:defprocess_request(self,request,spider):chrome_options=Options()chrome_options.add_argument('--headless')#使用headless谷歌浏览器模式chrome_options.add_argument('--disable-gpu')chrome_options.add_argument('--no-sandbox')#指定谷歌浏览器路径self.driver=webdriver.Chrome(chrome_options=chrome_options,executable_path='E:/pycharm/workspace/crawler/scrapy/chromedriver')ifrequest.url!='http://bbs.foodmate.net/':self.driver.get(request.url)html=self.driver.page_sourcetime.sleep(1)self.driver.quit()returnsscrapy.http.HtmlResponse(url=request.url,body=html.encode('utf-8'),encoding='utf-8',request=request)4.第4步:确定爬取数据的存储格式不用说了,根据根据自己的需要,在items.py中设置要爬取的数据格式。项目中引用这个格式保存即可:typelist:[LunTanContentInfoItem1,LunTanContentInfoItem2]article_url=Field()#str:url|文章链接scrapl_time=Field()#str:时间格式参考如下格式2019-08-0110:20:00|数据爬取timesource=Field()#str:字符类型|论坛名称eg:未名论坛、水木社区、天涯论坛type=Field()#str:字符类型|platetypeeg:'finance','sports','social'spider_type=Field()#str:forum|只写'forum'5.第五步:确保保存数据库。本项目选用的数据库是mongodb。既然是非关系型数据库,优势就很明显了。格式要求没那么高,可以灵活存储多维数据,一般爬虫首选数据库(别跟我说redis,会用就用,主要是不会)代码:importpymongoclassFMPipeline():def__init__(self):super(FMPipeline,self).__init__()#client=pymongo.MongoClient('139.217.92.75')client=pymongo.MongoClient('localhost')db=client.scrapy_FMself.collection=db.FMdefprocess_item(self,item,spider):query={'article_url':item['article_url']}self.collection.update_one(query,{"$set":dict(item)},upsert=True)returnitem这时候,一些聪明的朋友会问:同一个数据如果被爬取两次怎么办?(也就是查重功能)这个问题我之前没有考虑过,问了老大之后,程中知道我们保存数据的时候已经做了这个,就是这句话:query={'article_url':item['article_url']}self.collection.update_one(query,{"$set":dict(item)},upsert=True)通过帖子的链接判断是否存在数据爬取重复。如果重复可以理解为覆盖,也可以更新数据。6.其他设置如多线程和headers,Pipeline传输顺序等问题都在settings.py文件中设置。具体可以参考小编的项目来看,这里就不赘述了。七、效果展示1、点击运行,控制台会显示结果,如下图。2、中间会把很多帖子的爬取任务堆在队列里,然后多线程处理。我设置了16个线程,速度还是很可观的。3、数据库数据展示:content_info存储了每条帖子的所有评论和相关用户的公开信息。八。总结1.本文主要介绍了美食网站的数据采集和存储过程,详细讲解了如何分析网页结构、爬虫策略、网站类型、层级关系、爬虫方法和数据存储过程,最终实现邮政。每条评论都爬入数据库,可以更新数据,防止重复爬取、反爬取等,干货满满。2.这个项目总体来说难度不是特别大。只要思路正确,找到数据规律,可以说是轻而易举的上手了。我认为这很难,因为我以前没有经历过这个过程。就这么简单的介绍,希望能对您有所帮助,是我最大的荣幸。3、遇到问题,首先想到的不是问同事、朋友、老师,而是去谷歌、百度,看看有没有类似的情况,看看别人的经验。要学会自己发现问题、自己思考问题、自己解决问题。之后,工作会有很大的帮助(之前有说我学生时代还没过,但喜欢问问同事)。我在网上查了一些资料,还是没有头绪,再去问问别人,他们会更愿意帮忙。你的~
