动态渲染页面的爬取(项目案例:爬取今日头条热点新闻)

2024-04-22 11:48

本文主要是介绍动态渲染页面的爬取(项目案例:爬取今日头条热点新闻),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

声明:本文内容来自 张涛的《从零开始学Scrapy网络爬虫》

  • 在使用Selenium的过程中,我们驱动的都是Chrome、FireFox等有界面的浏览器,效率极低。对爬虫来说,只要能高效地获取数据,有无界面根本无关紧要,因此本项目选择使用无界面的浏览器PhantomJS。

1.准备工作

  • 项目开始强,要保证必要的环境已经成功搭建。主要有Selenium和PhantomJS。
  • (1)使用pip安装Selenium。
pip install selenium
  • (2)下载PhantomJS驱动并配置环境。
    在这里插入图片描述

2.创建Scrapy项目

  • 创建一个名为toutiao的scrapy项目。
 scrapy startproject toutiao

3.使用Item封装数据

  • 打开项目toutiao中的items.py源文件,添加新闻字段,实现代码如下:
import scrapyclass ToutiaoItem(scrapy.Item):title = scrapy.Field() # 标题source = scrapy.Field() # 来源comment = scrapy.Field() # 评论数

4.创建Spider源文件及Spider类

  • 在Spider文件夹中新建toutiao_spier.py文件。在toutiao_spider.py中创建爬虫类ToutiaoSpider,实现代码如下:
from scrapy import Request
import sys
sys.path.append('D:\\pythonProject\\scrapy\\toutiao')
from scrapy.spiders import Spiderfrom toutiao.items import ToutiaoItem # 导入Item模块
from selenium import webdriver # 导入浏览器引擎模块class ToutiaoSpider(Spider):# 定义爬虫名称name = 'toutiao'# 构造函数def __init__(self):# 生成PhantomJS的对象driverself.driver = webdriver.PhantomJS()# 获取初始的Requestdef start_requests(self):url = "https://www.toutiao.com/?channel=hot&source=ch" # 生成请求对象,设置urlyield Request(url)# 数据解析方法def parse(self,response):pass
  • 首先,导入必要的模块;接着,定义ToutiaoSpider类,类中定义了3个方法:
  • (1)init():构建函数 中生成了phantomjs的对象driver。
  • (2)start_requests():生成初始Request对象,虽然会被拦截,还是需要这一步。
  • (3)parse():数据解析功能暂不实现。

5.实现下载器中间件

  • 在新建项目时,自动生成了一个middlewares.py的源文件,叫做中间件。中间件包含爬虫中间件和下载器中间件,分别对应源文件中ToutiaoSpiderMiddleware 类 和 ToutiaoDownloaderMiddleware 类。下面就在ToutiaoDownloaderMiddleware类中实现使用Selenium请求和下载页面。
  • 以下为ToutiaoDownloaderMiddleware类实现的代码:
import time # 时间模块
from scrapy.http import HtmlResponse # html响应模块
from selenium.webdriver.common.by import By # By模块
from selenium.webdriver.support.wait import WebDriverWait # 等待模块
from selenium.webdriver.support import expected_conditions as EC # 预期条件模块# 异常模块
from selenium.common.exceptions import TimeoutException,NoSuchElementException
class ToutiaoDownloaderMiddleware(object):def process_request(self,request,spider):# 判断name是toutiao的爬虫if spider.name == "toutiao":# 打开URL对应的页面spider.driver.get(request.url)try:# 设置显式等待,最长等待5秒wait = WebDriverWait(spider.driver,5)# 等待新闻列表容器加载完成wait.until(EC.presence_of_element_located((By.XPATH,"//div[@class='wcommonFeed']")))# 使用JS的scrollTo方法实现将页面向下滚动到中间spider.driver.execute_script('window.scrollTo(0,document.body.scrollHeight/2)')for i in range(10):time.sleep(5)# 使用JS的scrollTo方法将页面滚动到最底端spider.driver.execute_script('window.scrollTo(0,document.body.scrollHeignt)')# 获取加载完成的页面源代码origin_code = spider.driver.page_source# 将源代码构造成一个Response对象并返回res = HtmlResponse(url=request.url,encodings="utf8",body=origin_code,request=request)return resexcept TimeoutException: # 超时print("time out")except NoSuchElementException: # 无此元素print("no such element")return None
  • 首先导入必要的模块,有时间模块、响应模块、By模块、等待模块、预期条件模块和异常模块。
  • ToutiaoDownloaderMiddleware 类中的process_request(self,request,spider)方法专门用于处理从爬虫发送过来的HTTP请求,共有两个参数:参数request传递HTTP请求对象;参数spider传递爬虫对象(一个项目可以有多个爬虫)。所有的功能都是在该方法中实现。
  • 在方法process_request()中,首先,通过spider.name == toutiao来确定要处理的请求是从名为toutiao的爬虫处传递的;然后,通过driver的get()方法实现使用Selenium获取指定的URL页面,并通过WebDriverWait()方法设置最长等待时间,等待新闻列表的div容器加载完成;接着,使用driver的execute_script()方法执行JS命令,将页面滚动到底部,无法加载更多内容);再每隔5秒钟,将页面滚动到最底部(重复10次),这样页面就会不断加载更多新闻内容;最后,通过driver.page_source()方法获取加载完整的页面文档构造一个Response对象,返回给爬虫。

6.开启下载器中间件

  • 下载器中间件默认关闭,需要手动开启。在settings.py中将对应的注释放开即可,代码如下:

在这里插入图片描述

7.解析数据(我写的是完整代码)

  • 下载器中间件构造一个Response对象后,将其发送给ToutiaoSpider爬虫类的parse()方法,实现数据的解析。再回到ToutiaoSpider类,完成parse()方法。parse()方法的实现代码如下:
from scrapy import Request
import sys
sys.path.append('D:\\pythonProject\\scrapy\\toutiao')
from scrapy.spiders import Spiderfrom toutiao.items import ToutiaoItem # 导入Item模块
from selenium import webdriver # 导入浏览器引擎模块class ToutiaoSpider(Spider):# 定义爬虫名称name = 'toutiao'# 构造函数def __init__(self):# 生成PhantomJS的对象driverself.driver = webdriver.PhantomJS()# 获取初始的Requestdef start_requests(self):url = "https://www.toutiao.com/?channel=hot&source=ch" # 生成请求对象,设置urlyield Request(url)# 数据解析方法def parse(self,response):item = ToutiaoItem()list_selector = response.xpath("//div[@class='wcommonFeed']/u1/li")for li in  list_selector:try:# 标题title = li.xpath(".//a[@class='link title']/text()").extract()# 去除空格title = title[0].strip(" ")# 来源source = li.xpath(".//a[@class='lbtn source']/text()").extract()# 去除点号和全角空格source = source[0].strip(". ").strip(" ")# 评论数comment = li.xpath(".//a[@class='lbtn comment']/text()")# 去除文字及空格comment = comment.re("(.*?)评论")[0]comment = "".join(comment.split()) # 去除空格:&nbspitem["title"] = title # 标题item["source"] = source # 来源item["comment"] = comment # 评论数yield itemexcept:continue
  • 在Chrome浏览器的“开发者工具”中的Element选项卡中,显示的就是加载完全的HTML代码(包括AJAX加载的数据),如下图所示。通过对HTML代码的分析,就能很容易地实现数据解析了。
    -

我一直没找到div[@class=‘wcommonFeed’],希望大佬们可以看看,这个属性是在哪里的?

8.运行爬虫

  • 通过命令运行爬虫,将数据保存于toutiao.csv文件中。
scrapy crawl toutiao -o toutiao.csv
  • 第一次运行,出现以下报错信息
    在这里插入图片描述
  • 解决措施,详见https://blog.csdn.net/u010358168/article/details/79749149
    在这里插入图片描述
  • 再次运行,虽然没有报错,但是得到仍然是空的csv文件,按照书上建议(1)
    -
  • 仍然是没有数据结果,希望发现问题所在的大佬解答哈

这篇关于动态渲染页面的爬取(项目案例:爬取今日头条热点新闻)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/925696

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

配置springboot项目动静分离打包分离lib方式

《配置springboot项目动静分离打包分离lib方式》本文介绍了如何将SpringBoot工程中的静态资源和配置文件分离出来,以减少jar包大小,方便修改配置文件,通过在jar包同级目录创建co... 目录前言1、分离配置文件原理2、pom文件配置3、使用package命令打包4、总结前言默认情况下,

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进

vue基于ElementUI动态设置表格高度的3种方法

《vue基于ElementUI动态设置表格高度的3种方法》ElementUI+vue动态设置表格高度的几种方法,抛砖引玉,还有其它方法动态设置表格高度,大家可以开动脑筋... 方法一、css + js的形式这个方法需要在表格外层设置一个div,原理是将表格的高度设置成外层div的高度,所以外层的div需要

IDEA运行spring项目时,控制台未出现的解决方案

《IDEA运行spring项目时,控制台未出现的解决方案》文章总结了在使用IDEA运行代码时,控制台未出现的问题和解决方案,问题可能是由于点击图标或重启IDEA后控制台仍未显示,解决方案提供了解决方法... 目录问题分析解决方案总结问题js使用IDEA,点击运行按钮,运行结束,但控制台未出现http://