首先明确需求:爬取网易新闻新闻的标题和新闻详情页的内容
注意项:
创建工程:scrapy startproject wangyiPro
转入工程:cd wangyiPro
创建爬虫文件:scrapy genspider
观察网易新闻的首页,配套开发者工具,定位到需要爬取的模块,编写parse方法获取url
wangyi.py
from selenium import webdriver
from wangyiPro.items import WangyiproItem
import scrapy# 需求,爬取五大板块下的新闻内容和标题,内容在新闻详情页面中,标题在对应模块下
# 各个模块下的内容是 动态加载的 可配合selenium实现动态加载
# 详情页面的爬取class WangyiSpider(scrapy.Spider):name = 'wangyi'# allowed_domains = [']start_urls = ['/']model_urls = []def parse(self, response):# 获取不同模块下的url,放入model_urls中li_list = response.xpath('//div[@class="ns_area list"]/ul/li')url_list = [2, 3, 5, 6, 10]for index in url_list:# 不同模块下对应的urlurl = li_list[index]model_url = url.xpath('./a/@href').extract_first()del_urls.append(model_url)# 对不同模块下的url进行请求yield scrapy.Request(model_url, callback=self.parse_model)
对不同模块的url发起请求后,不难发现新闻有个明显的加载,这个动态加载的表现,为获取到动态加载的数据,可配合selenium使用。
先在 wangyi.py文件中实例化一个浏览器对象
wangyi.py
# 实例化一个浏览器对象def __init__(self):# from selenium import webdriverself.options = webdriver.ChromeOptions()# 添加“取消侦听提示”的配置项self.options.add_experimental_option('excludeSwitches', ['enable-logging'])self.driver = webdriver.Chrome(executable_path=r"C:UsersvidfuPycharmProjects", options=self.options)
之后,在middlewares.py文件的WangyiproDownloaderMiddleware
类中的process_response
方法中编写代码
middlewares.py
# 拦截5个请求的响应体,进行篡改def process_response(self, request, response, spider):# spider 是爬虫对象# response 是响应对象# 实例化一个新的响应对象(符合所有需求,包括动态加载出数据),代替原来的响应对象# 问题-如何动态加载数据?:基于selenium获取动态加载的数据# 通过url指定request,request指定对应的response# 获取在爬虫类中定义的浏览器驱动对象bro = spider.driver# 拦截到的响应在5给模块中,就换一个新的响应体if request.url del_urls:# 获取请求(request.url)sleep(5)# 获取到的数据中包含了动态加载page_text = bro.page_source# from scrapy.http import HtmlRespon# 新的响应体new_response = HtmlResponse(url=request.url,body=page_text,encoding='utf-8',request=request)return new_responseelse:return response
对1.1获取到的模块url发起请求,在items.py
文件中设置字段,获取新闻标题和新闻内容,最后关闭驱动
wangyi.py
# 对不同模块url进行请求, 不同板块的新闻内容是动态加载的def parse_model(self, response):div_list = response.xpath('//div[@class="ndi_main"]/div')for div in div_list:# 实例化item对象item = WangyiproItem()item['title'] = div.xpath('./div/div[1]/h3/a/text()').extract_first()detail_url = div.xpath('./div/div[1]/h3/a/@href').extract_first()yield scrapy.Request(detail_url, callback=self.parse_detail, meta={'item': item})# 对详情页面进行解析def parse_detail(self, response):item = a['item']item['content'] = ''.join(response.xpath('//div[@class="post_body"]//text()').extract())yield item# 关闭开启的驱动def colse(self, spider):self.driver.quit()
设置User-Agent、robots协议、日志等级、开启管道和中间件,要看一下爬取的内容,在管道类WangyiproPipeline
打印出来
setting.py
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43'
# rules
ROBOTSTXT_OBEY = False
LOG_LEVEL = 'ERROR'
DOWNLOADER_MIDDLEWARES = {'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543,
}
ITEM_PIPELINES = {'wangyiPro.pipelines.WangyiproPipeline': 300,
}
遇到一个问题,虽然有打印输出,但是在打印之前会提示”typeerror: request url must be str or unicode, got nonetype“,我在想是我详情页面的url类型出错了吗?,我检查了一下,没检查出个所以然来,没影响输出就不管了,如果有大佬知道是怎么回事,欢迎评论留言。
本文发布于:2024-02-02 12:59:38,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170684997643961.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |