Loading... # 爬虫部分 书接上回,我们讲到,要用elasticsearch来存储信息,那么我们首先就得安装elasticsearch。这里就不介绍了,默认已经装好elasticsearch,那我们就正式开始写爬虫了。 ## 1. Scrapy创建爬虫项目 ```shell (baidunewsspider) C:\Users\LiTangMM\PycharmProjects>scrapy startproject baiduNewsSpider (baidunewsspider) C:\Users\LiTangMM\PycharmProjects\baiduNewsSpider>scrapy genspider newsbaidu http://ne ws.baidu.com/ ``` ![在这里插入图片描述](/usr/uploads/2021/03/827008059.png) 终端显示如上就说明爬虫已经创建好了。 ![在这里插入图片描述](/usr/uploads/2021/03/4123531666.png) 项目长这样。 ## 2. 爬取新闻链接 ### 2.1 定义字段 我们首先得告诉scrapy,我们要哪些数据,编辑baiduNewsSpider/items.py 文件: ```python # -*- coding: utf-8 -*- # Define here the models for your scraped items # # See documentation in: # https://doc.scrapy.org/en/latest/topics/items.html import scrapy class BaidunewsspiderItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() news_url = scrapy.Fileld() # 新闻链接 pass ``` > pass 可以只是为了代码块完整性才加的,可以删除。 ### 2.2 实现newsbaidu.py OK!下面就是爬取了,修改baiduNewsSpider/spiders/newsbaidu.py文件 ```python # -*- coding: utf-8 -*- import scrapy import json import re from baiduNewsSpider.items import BaidunewsspiderItem class NewsbaiduSpider(scrapy.Spider): name = 'newsbaidu' allowed_domains = ['http://news.baidu.com/'] start_urls = [] def start_requests(self): # 重写请求构造函数 baseurl = 'http://news.baidu.com/widget?id={}&ajax=json&t=1565919256596' widget_ids = ['civilnews', 'InternationalNews', 'EnterNews', 'SportNews', 'FinanceNews', 'TechNews', 'MilitaryNews', 'InternetNews', 'DiscoveryNews', 'LadyNews', 'HealthNews', 'PicWall'] return [scrapy.FormRequest(baseurl.format(_)) for _ in widget_ids] def parse(self, response): # 解析函数 widgetid = re.match(r'.*?id=(.*?)&', response.url).group(1) # 从response中提取url,使用正则匹配提取id值 jsondate = json.loads(response.text) # 将response的内容使用json解析 news_list = jsondate.get('data').get(widgetid).get('focusNews') # 提取内容 for news in news_list: yield BaidunewsspiderItem(news_url=news['m_url']) # 返回一个迭代器 ``` ### 2.3 爬取并保存 打开shell,输入*scrapy crawl newsbaidu -o urls.csv* 启动爬虫。 ![在这里插入图片描述](/usr/uploads/2021/03/1199291839.png) 我们使用命令将数据爬取并保存下来。 ## 3. 爬取新闻内容 ### 3.1 创建另一个爬虫 *scrapy genspider newsspider* ![在这里插入图片描述](/usr/uploads/2021/03/1815850453.png) ### 3.2 定义item ```python class NewsItem(scrapy.Item): url = scrapy.Field() # 新闻链接 title = scrapy.Field() # 新闻标题 content = scrapy.Field() # 新闻内容 ``` ### 3.3 实现newsspider.py 首先,得从文件中读取到新闻的url,所以我们得重写 start_requests 方法 ### 3.3 定义爬虫 ```python # -*- coding: utf-8 -*- import scrapy from baiduNewsSpider.items import NewsItem class NewsspiderSpider(scrapy.Spider): name = 'newsspider' allowed_domains = [''] start_urls = [''] def start_requests(self): with open('url.csv') as urlfile: urllist = urlfile.readlines()[1:] return [scrapy.FormRequest(_) for _ in urllist] def parse(self, response): url = response.url urlname = url.split('/')[2] # 使用split切割url,判断url属于那个网站 if urlname == '3w.huanqiu.com': # 环球网 title = response.xpath('//h1[@class="a-title"]/strong/text()').extract()[0] #使用 response的selector解析 网页 content = ''.join(response.xpath('//div[@class="a-con"]/p/text()').extract()) elif urlname == 'baijiahao.baidu.com': # 百家号 title = response.xpath('//div[@class="article-title"][1]/h2/text()').extract()[0] content = ''.join(response.xpath('//div[@id="article"]//text()').extract()) elif urlname == 'news.cctv.com': # 央视新闻 title = response.xpath('//div[@class="cnt_bd"][1]/h1/text()').extract()[0] content = ''.join(response.xpath('//div[@class="cnt_bd"][1]/p/text()').extract()) else: # 其他 title = response.xpath('//h/text()').extract()[0] content = ''.join(response.xpath('//p/text(').extract()) yield NewsItem(title=title, url=url, content=content) ``` ### 3.4 自定义管道 要把数据存到elasticsearch中,首先,我们得安装好elasticsearch-dsl。 ```shell pip install elasticsearch-dsl ``` 接着在根目录新建一个models.py 文件,它将负责映射: ```python from elasticsearch_dsl import DocType, Keyword, Text from elasticsearch_dsl.connections import connections connections.create_connection(hosts=['localhost']) class NewsType(DocType): title = Keyword # title不作分词 content = Text(analyzer='ik_max_word') #内容使用ik最大分词 class Meta: index = 'baidunews' doc_type = 'news' if __name__=='main': NewsType.init() ``` 最后实现一个 pipline类: ```python # -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to the ITEM_PIPELINES setting # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html from baiduNewsSpider.models import NewsType class ElastisearchPipeline(object): def process_item(self, item, spider): if spider.name == 'newsspider': # 如果是新闻爬虫,存到elasticsearch中 news = NewsType() news.title = item['title'] news.content = item['content'] news.save() return item ``` 我们还要记得在配置中将这个管道加上。 ![在这里插入图片描述](/usr/uploads/2021/03/2915484587.png) > 为保证正确运行,请确认elasticsearch已打开,ik分词器以安装。注意elasticsearch版本号一定要和ik分词器版本号一样,否则elasticsearch会启动不了。 运行 model.py 文件创建索引。 运行爬虫。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190816150945370.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MDQxMjEw,size_16,color_FFFFFF,t_70) OK!到这里,我们的爬虫部分完成了,接下来,我们将使用django搭建一个rest服务。 转载至CSDN博主:[[李唐敏民](https://blog.csdn.net/qq_39041210 "李唐敏民")] -------------------------- 最后修改:2024 年 06 月 18 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏