Python爬虫爬取豆瓣电影短评(爬虫入门,Scrapy框架,Xpath解析网站,jieba分词)

声明:以下内容仅供学习参考,禁止用于任何商业用途

很久之前就想学爬虫了,但是一直没机会,这次终于有机会了

主要参考了《疯狂python讲义》的最后一章

首先安装Scrapy:

pip install scrapy

然后创建爬虫项目:

scrapy startproject 项目名

然后项目里面大概是长这样的:

__pycache__是python缓存,可以不管

scrapy.cfg是scrapy框架自带的配置文件,这个项目里面可以不用改

settings.py里面是爬虫的设置,可以在里面设置爬虫模仿的浏览器型号,以及访问一个页面的延迟(防止被反爬虫),以及是否遵循爬虫规则、是否使用cookies等等:

# Scrapy settings for exp1 project
#
# For simplicity, this file contains only settings considered important or
# commonly used. You can find more settings consulting the documentation:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.htmlBOT_NAME = "exp1"SPIDER_MODULES = ["exp1.spiders"]
NEWSPIDER_MODULE = "exp1.spiders"# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = "exp1 (+http://www.yourdomain.com)"# Obey robots.txt rules
ROBOTSTXT_OBEY = True# Configure maximum concurrent requests performed by Scrapy (default: 16)
#CONCURRENT_REQUESTS = 32# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 2
# The download delay setting will honor only one of:
#CONCURRENT_REQUESTS_PER_DOMAIN = 16
#CONCURRENT_REQUESTS_PER_IP = 16# Disable cookies (enabled by default)
COOKIES_ENABLED = False# Disable Telnet Console (enabled by default)
#TELNETCONSOLE_ENABLED = False# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; Win 64; x64; rv:61.0) Gecko/20100101Firefox/61.0','Accept' : 'text/htmp,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
}# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
#SPIDER_MIDDLEWARES = {
#    "exp1.middlewares.Exp1SpiderMiddleware": 543,
#}# Enable or disable downloader middlewares
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#DOWNLOADER_MIDDLEWARES = {
#    "exp1.middlewares.Exp1DownloaderMiddleware": 543,
#}# Enable or disable extensions
# See https://docs.scrapy.org/en/latest/topics/extensions.html
#EXTENSIONS = {
#    "scrapy.extensions.telnet.TelnetConsole": None,
#}# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {"exp1.pipelines.Exp1Pipeline": 300,
}# Enable and configure the AutoThrottle extension (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/autothrottle.html
AUTOTHROTTLE_ENABLED = True
# The initial download delay
AUTOTHROTTLE_START_DELAY = 5
# The maximum download delay to be set in case of high latencies
AUTOTHROTTLE_MAX_DELAY = 60
# The average number of requests Scrapy should be sending in parallel to
# each remote server
AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
# Enable showing throttling stats for every response received:
#AUTOTHROTTLE_DEBUG = False# Enable and configure HTTP caching (disabled by default)
# See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
#HTTPCACHE_ENABLED = True
#HTTPCACHE_EXPIRATION_SECS = 0
#HTTPCACHE_DIR = "httpcache"
#HTTPCACHE_IGNORE_HTTP_CODES = []
#HTTPCACHE_STORAGE = "scrapy.extensions.httpcache.FilesystemCacheStorage"# Set settings whose default value is deprecated to a future-proof value
REQUEST_FINGERPRINTER_IMPLEMENTATION = "2.7"
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
FEED_EXPORT_ENCODING = "utf-8"

爬虫需要爬取的内容定义在items.py里面:

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass Exp1Item(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 电影名film_name = scrapy.Field()# 评论用户名user_name = scrapy.Field()# 评论时间comment_time =scrapy.Field()# 评论内容comment = scrapy.Field()

middlewares.py应该是中间件的定义,不是很明白它的工作原理,应该也不用改

pipelines.py是将爬取到的内容进行输出保存等处理的管道,也负责一些预处理和后处理的任务,例如把文件保存为json格式:

# 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
import json# useful for handling different item types with a single interface
from itemadapter import ItemAdapterclass Exp1Pipeline(object):def __init__(self):self.json_file = open("data6.json","wb+")self.json_file.write('[\n'.encode("utf-8"))def close_spider(self, spider):print('--------关闭文件--------')self.json_file.seek(-2,1)self.json_file.write('\n]'.encode("utf-8"))self.json_file.close()def process_item(self, item, spider):print("电影名: ",item['film_name'])print("评论用户: ",item['user_name'])print("评论时间: ",item['comment_time'])print("评论内容: ",item['comment'])text = json.dumps(dict(item), ensure_ascii = False) + ",\n"self.json_file.write(text.encode("utf-8"))

spiders文件夹里面主要用来存储爬虫的主体

爬虫中的访问网页可以直接用scrapy.Request(网址,回调函数名,传参内容(可选))接口进行访问下一个网页。

接下来就是愉快的解析网站时间

由于本人刚入门爬虫技术有限,但是又时间紧迫,所以就只爬了豆瓣top250的电影的短评

首先进入top250的界面按F12查看源码

我们在榜单需要爬取的只有当前页的所有电影链接和下页的链接

我们可以使用scrapy shell协助我们解析网站

首先在终端输入:

scrapy shell -s USER_AGENT='Mozilla/5.0' 网址

接下来就会出现一个很酷的scrapy终端:

接下来我们先学习一下Xpath的用法

在F12打开的右半边窗口中,点击选择按钮

选择一个幸运的网页对象,点击一下

可以发现右侧窗口自动定位到了网页对应的源码

我们只需要从上到下找这些朝下的小三角形,就知道我们选择的内容具体位于哪一层

最终发现是位于:(电影网址)

body->div(id="wrapper")->div(id="content")->div->div(class="article")->ol

->li->div->div(class="info")->div(class="hd")->a节点的href属性

然后把上面这段话转换为Xpath的表达方式就是:

response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/ol/li/div/div[@class="info"]/div[@class="hd"]/a/@href')

具体解释一下:

// 表示匹配任意位置的节点

/ 表示匹配根节点

. 表示匹配当前位置的节点

.. 表示匹配父节点

@ 表示匹配属性

[] 里面表示对当前节点属性的限制(需要加限制的节点一般都是同层级下有相同节点名的节点)

然后把这段话输入进scrapy shell

发现它查出来了一大堆奇奇怪怪的东西:

这其实只是我们没有对内容进行解包,对Xpath的结果调用一下.extract()函数就行了

然后就会发现它的内容是一个列表:

接下来我们只需要依葫芦画瓢就行,把剩下的网站内容依次解析即可

至于为什么没有爬长评,是因为不会处理javascript的网站,但是短评就可以直接解析获取

不过selenium是可以做到的,具体怎么做还需要进一步的学习(挖坑)

但是selenium速度似乎好像会慢一些?

最后就是一些写爬虫的SB错误

之前不太理解yield的机制,搞了半天,发现爬虫爬取的顺序还是有很大问题,结果是用了全局变量导致它发生数据读写冲突了然后就寄了,最后通过Request传参,再用dict保存每个回调函数中获取的下一页位置,这才把问题解决了。另外那个cnt是因为豆瓣似乎限制了短评查看只能查看前10页,后面会无权访问?反正加一下也不是什么大事,但是也要注意不要使用全局变量。

温馨提示:这个代码爬两万条左右短评就会被封号(为了完成5w条的作业要求,被迫封了两个ip)(反反爬虫技术还是太菜了)似乎豆瓣并不是通过ip访问频率来判断爬虫的,而是用ip访问总次数来判断的???

dbspd.py:

import scrapy
from exp1.items import Exp1Itemclass DoubanSpider(scrapy.Spider):name = 'douban'allowed_domain = ['movie.douban.com']start_urls = ['https://movie.douban.com/top250?start=0&filter=']comment_page_sub = '/comments?sort=time&status=P'cnt = {}film_pre = {}def parse_film(self, response):film_name = (response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/h1/text()').extract())[0].split(" ")[0]self.film_pre[film_name] = response.meta['fp']user_name_list = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/div[@id="comments"]/div/div[@class="comment"]/h3/span[@class="comment-info"]/a/text()').extract()comment_time_list = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/div[@id="comments"]/div/div[@class="comment"]/h3/span[@class="comment-info"]/span[@class="comment-time "]/text()').extract()comment_list = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/div[@id="comments"]/div/div[@class="comment"]/p/span/text()').extract()for (user_name,comment_time,comment) in zip(user_name_list,comment_time_list,comment_list):item = Exp1Item()item['film_name'] = film_nameitem['user_name'] = user_nameitem['comment_time'] = comment_time.split(" ")[20] + " " + comment_time.split(" ")[21][0:8]item['comment'] = commentyield itemnew_links_sub = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/div[@id="comments"]/div[@id="paginator"]/a[@class="next"]/@href').extract()this_film_pre = self.film_pre.get(film_name, self.film_pre)this_film_cnt = self.cnt.get(film_name, 0)if(this_film_cnt < 8):print("next_page url:",this_film_pre + "comments" + new_links_sub[0])self.cnt[film_name] = this_film_cnt + 1yield scrapy.Request(this_film_pre + "comments" + new_links_sub[0], callback=self.parse_film, meta={'fp':self.film_pre[film_name]})def parse(self, response):film_list = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/ol/li/div/div[@class="info"]/div[@class="hd"]/a/@href').extract()for film_pre in film_list:yield scrapy.Request(film_pre + self.comment_page_sub , callback=self.parse_film, meta={'fp':film_pre})new_links_sub = response.xpath('//body/div[@id="wrapper"]/div[@id="content"]/div/div[@class="article"]/div[@class="paginator"]/span[@class="next"]/a/@href').extract()print("next_rank_page url:","https://movie.douban.com/top250" + new_links_sub[0])yield scrapy.Request("https://movie.douban.com/top250" + new_links_sub[0], callback=self.parse)

最后用命令

scrapy crawl douban

就可以运行我们的爬虫啦!!

最后的最后,再提一嘴分词

先装一个jieba库

pip install jieba

然后直接开用lcut()函数就行了,禁用词列表在stop.txt中,一行一个

另外不知道为什么换行等一些空字符也会出现在分词结果中,所以还得单独处理一下。

import jieba
import json
stop = open("stop.txt", "r", encoding='utf-8').read()
stop = stop.splitlines()
# print(stop)txt = open("film_comment_data.txt", "r", encoding='utf-8').read()
d = json.loads(txt)
cnt = 0
word_file = open("word.txt","wb+")
for item in d:words = jieba.lcut(item['comment'])print(cnt)cnt+=1for word in words:if word in stop:passelse:if word != "\n":word = word + "\n"word_file.write(word.encode("utf-8"))
word_file.close()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣26:删除有序数组中的重复项

26. 删除有序数组中的重复项 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 …

Leetcode 95. 不同的二叉搜索树 II

文章目录 题目代码&#xff08;9.21 首刷看解析&#xff09; 题目 Leetcode 95. 不同的二叉搜索树 II 代码&#xff08;9.21 首刷看解析&#xff09; class Solution { public:vector<TreeNode*> generateTrees(int n) {return build(1,n);}vector<TreeNode*> bu…

将本地前端工程中的npm依赖上传到Nexus

【问题背景】 用Nexus搭建了内网的依赖仓库&#xff0c;需要将前端工程中node_modules中的依赖上传到Nexus上&#xff0c;但是node_modules中的依赖已经是解压后的状态&#xff0c;如果直接机械地将其简单地打包上传到Nexus&#xff0c;那么无法通过npm install下载使用。故有…

Jenkins Job的Migrate之旅

场景 使用Jenkins 做为应用的定时任务处理&#xff0c; 在上面建立的800个左右的Job, 这个环境运行了很多年&#xff0c; 当初安装的最新版本是Jenkins 1.642.3&#xff0c; 现在因为OS需要升级等原因&#xff0c; 驻在上面的Jenkins 服务器也需要一并升级&#xff0c;在新的服…

Mock.js之Element-ui搭建首页导航与左侧菜单

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《springMvc使用》 ⛺️ 生活的理想&#xff0c;为了不断更新自己 ! 1、Mock.js的使用 1.1.什么是Mock.js Mock.js是一个模拟数据的生成器&#xff0c;用来帮助前…

浅谈C++|文件篇

C中的文件操作是通过使用文件流来实现的。文件流提供了对文件的输入和输出功能。下面是C文件操作的基本步骤&#xff1a; 1. 包含头文件&#xff1a;首先&#xff0c;包含 <fstream> 头文件&#xff0c;它包含了进行文件操作所需的类和函数。 2 . 进行文件读写操作&#…

9领域事件

本系列包含以下文章&#xff1a; DDD入门DDD概念大白话战略设计代码工程结构请求处理流程聚合根与资源库实体与值对象应用服务与领域服务领域事件&#xff08;本文&#xff09;CQRS 案例项目介绍 # 既然DDD是“领域”驱动&#xff0c;那么我们便不能抛开业务而只讲技术&…

Windows专业版的Docker下载、安装与启用Kubenetes、访问Kubernetes Dashboard

到Docker 官网https://www.docker.com/ 下载windows操作系统对应的docker软件安装 Docker Desktop Installer-Win.exe 2023-09版本是4.23 下载后双击安装 重启windows后&#xff0c;继续安装 接受服务继续安装 解决碰到的Docker Engine stopped 打开 控制面板》程序》启用或关…

软件测试/测试开发丨利用人工智能ChatGPT自动生成PPT

点此获取更多相关资料 简介 PPT 已经渗透到我们的日常工作中&#xff0c;无论是工作汇报、商务报告、学术演讲、培训材料都常常要求编写一个正式的 PPT&#xff0c;协助完成一次汇报或一次演讲。PPT相比于传统文本的就是有布局、图片、动画效果等&#xff0c;可以给到观众更好…

第一百五十四回 如何实现滑动菜单

文章目录 概念介绍实现方法示例代码体验分享 我们在上一章回中介绍了滑动窗口相关的内容相关的内容&#xff0c;本章回中将介绍如何实现 滑动菜单.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在本章回中介绍的滑动菜单表示屏幕上向左或者向右滑动滑动时弹…

自注意力机制

回顾以下注意力机制&#xff1a; 自注意力机制 Self-Attention的关键点 在于 K ≈ \approx ≈V ≈ \approx ≈Q 来源于同一个X&#xff0c;三者是同源的&#xff0c;通过 W Q W_Q WQ​, W K W_K WK​, W V W_V WV​做了一层线性变换。 接下来步骤和注意力机制一模一样。 …

基于微信小程序的线上教育课程付费商城(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

【项目实战】Linux系统下jar包自启动

什么是jar包自启动 在Linux系统中&#xff0c;"jar包自启动"是指通过配置将Java程序打包成可执行的Jar文件&#xff0c;并设置其在系统启动时自动运行。以下是与jar包自启动相关的一些概念&#xff1a; Jar文件&#xff1a;Jar&#xff08;Java Archive&#xff09…

K-最近邻算法

一、说明 KNN算法是一个分类算法&#xff0c;基本数学模型是距离模型。K-最近邻是一种超级简单的监督学习算法。它可以应用于分类和回归问题。虽然它是在 1950 年代引入的&#xff0c;但今天仍在使用。然而如何实现&#xff0c;本文将给出具体描述。 来源&#xff1a;维基百科 …

高速USB转4路RS422串口

基于480Mbps 高速USB转8路串口芯片CH344Q&#xff0c;可以为各类主机扩展出4个独立的串口。CH344芯片支持使用操作系统内置的CDC串口驱动&#xff0c;也支持使用厂商提供的VCP串口驱动程序&#xff0c;可支持Windows、Linux、Android、macOS等操作系统。因CDC类协议和类驱动的原…

Android 10.0 系统开启和关闭黑白模式主题功能实现

1. 概述 在10.0的rom系统开发定制化中,在系统SystemUI的下拉状态栏中,产品开发功能需求要求添加黑白模式功能开关的功能,就是打开黑白模式,系统颜色就会变成黑白颜色, 关闭黑白模式开关系统就会变成彩色模式,所以就需要了解下系统是怎么设置黑白模式和彩色模式的,然后添…

DA3 网站的第10位用户信息读取

目录 1.题目描述 2.输入描述 3.输出描述 4.题目分析 5.通过代码 1.题目描述 现有一个Nowcoder.csv文件&#xff0c;它记录了牛客网的部分用户数据&#xff0c;包含如下字段&#xff08;字段与字段之间以逗号间隔&#xff09;&#xff1a; Nowcoder_ID&#xff1a;用户ID …

git:一、GIT介绍+安装+全局配置+基础操作

版本管理系统&#xff08;SVN和Git&#xff09;&#xff1a; 集中式版本控制系统&#xff08;SVN&#xff09; SVN是集中式版本控制系统&#xff0c;版本库是集中放在中央服务器的. 工作流程如下: 1.从中央服务器远程仓库下载代码 2.修改后将代码提交到中央服务器远程仓库…

with ldid... /opt/MonkeyDev/bin/md: line 326: ldid: command not found

吐槽傻逼xcode 根据提示 执行了这个脚本/opt/MonkeyDev/bin/md 往这里面添加你brew install 安装文件的目录即可

华为云云耀云服务器L实例评测|如何保障华为云云耀云服务器L实例的安全和性能

引言 云耀云服务器L实例是华为云提供的高性能计算实例&#xff0c;为用户提供稳定可靠的云计算环境。为了保障实例的安全和性能&#xff0c;用户可以通过设置防火墙和安全组策略来限制网络访问和防止恶意攻击。华为云提供了灵活的管理工具&#xff0c;用户可以通过控制台、API…