免责声明:本文所记录的技术手段及实现过程,仅作为爬虫技术学习使用,不对任何人完全或部分地依据本文的全部或部分内容从事的任何事情和因其任何作为或不作为造成的后果承担任何责任。
爬取需求:爬取网易新闻【news.163.com】首页展示的相关新闻的标题、时间、来源、内容、链接
爬取工具:chrome浏览器、pycharm
Python库:scrapy
01
网站结构分析
通过输入【news.163.com】,打开网易新闻网站首页:
通过右键检查,打开网页新闻html分析页面,查看相关新闻链接信息:
新闻链接如下所示:
https://www.163.com/news/article/GDOVV60I000189FH.html
https://www.163.com/news/article/GDOPBQ3L000189FH.html
https://www.163.com/news/article/GDOPFUGJ000189FH.html
通过打开以上新闻链接,在新闻详情内可以爬取要求的相关字段信息。
02
创建Scrapy爬虫
打开命令行,创建Scrapy工程和爬虫:
scrapy startproject test001
cd news_spider
scrapy genspider -t crawl news_163 news.163.com
Scrapy工程创建成功!
03
首页新闻链接匹配
根据上面章节分析的新闻链接,通过正则表达式进行匹配:
https://www.163.com/news/article/GDOVV60I000189FH.html
https://www.163.com/news/article/GDOPBQ3L000189FH.html
https://www.163.com/news/article/GDOPFUGJ000189FH.html
总结上述链接规律,正则表达式如下:
https://www.163.com/news/article/.*?.html
修改爬虫代码,查看新闻链接匹配情况:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
class News163Spider(CrawlSpider):
name = 'news_163'
allowed_domains = ['news.163.com']
start_urls = ['https://news.163.com/']
rules = (
Rule(LinkExtractor(allow=r'https://www.163.com/news/article/.*?.html'), callback='parse_item', follow=True),
)
def parse_item(self, response):
item = {}
#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
#item['name'] = response.xpath('//div[@id="name"]').get()
#item['description'] = response.xpath('//div[@id="description"]').get()
return item
命令行执行爬虫:scrapy crawl news_163
查看爬虫运行情况,发现只匹配了1个新闻链接就不再执行,检查提示信息,发现是请求到了:www.163.com,与程序自动生成的domain不一致,所以需要修改后再试。
allowed_domains = ['163.com']
再次命令行运行爬虫
出现了大量的新闻链接,说明网易新闻的链接匹配成功!
04
新闻Items定义
根据爬取需求,定义新闻的Items字段
import scrapy
class NewsSpiderItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
news_title = scrapy.Field()
news_time = scrapy.Field()
news_content = scrapy.Field()
news_source = scrapy.Field()
news_url = scrapy.Field()
在【news_163.py】中引入刚刚定义好的Items:
from ..items import NewsSpiderItem
在【parse_item】方法中初始化定义好的Items
item = NewsSpiderItem()
定义的Items已经引入并初始化,后续爬取解析相关信息进行赋值即可。
05
新闻解析
首先解析新闻标题,打开新闻详情页,找到新闻解析的关键信息
编写代码提取标题信息
def get_news_title(self, response):
news_title = response.css('.post_title::text').extract()
if news_title:
return news_title[0]
return ''
在【parse_item】方法中调用提取标题的方法
item['news_title'] = self.get_news_title(response)
运行爬虫代码,结果如下
标题爬取成功!
依次类推,依次爬取来源、时间、内容等信息的爬取编码。
06
导出所有信息
打开工程内【pipelines】文件,开始编写导出代码
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from scrapy.exporters import CsvItemExporter
class NewsSpiderPipeline:
def __init__(self):
self.file = open('news_data.csv', 'wb')
self.exporter = CsvItemExporter(self.file, encoding = 'utf-8')
self.exporter.start_exporting()
def close_spider(self):
self.exporter.finish_exporting()
self.file.close()
def process_item(self, item, spider):
self.exporter.export_item(item)
return item
打开【settings】文件,打开pipeline的注释
ITEM_PIPELINES = {
'news_spider.pipelines.NewsSpiderPipeline': 300,
}
运行代码,在工程根目录下生成了【news_data.csv】文件,爬取网易新闻成功!
所有示例代码均可通过微信公众号回复关键字【pachong23】下载!