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

news2024/11/25 14:40:23

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

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

主要参考了《疯狂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.html

BOT_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.html

import scrapy


class 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 ItemAdapter


class 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 Exp1Item

class 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_name
            item['user_name'] = user_name
            item['comment_time'] = comment_time.split(" ")[20] + " " + comment_time.split(" ")[21][0:8]
            item['comment'] = comment
            yield item
        new_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 + 1
            yield 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+=1
    for word in words:
        if word in stop:
            pass
        else:
            if word != "\n":
                word = word + "\n"
                word_file.write(word.encode("utf-8"))
word_file.close()

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

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

相关文章

广东MES系统实现设备管理的方法与功能

在生产车间中&#xff0c;可以借助MES系统来完成设备管理。下面来看看借助MES系统实现设备管理比较常见的具体方法与功能&#xff1a; 1.在线监控和数据采集&#xff1a;MES系统能够与车间设备相连接&#xff0c;在线实时监控设备的运行状态和运行指标。凭借传感器、物联网产品…

【教程】Ubuntu自动查看有哪些用户名与密码相同的账户,并统一修改密码

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 目录 背景说明 开始操作 修改密码 背景说明 有些用户为了图方便或者初始创建用户默认设置等原因&#xff0c;会将密码设置为与用户名相同&#xff0c;但这就使得非常不安全。甚至如果该用户具有sudo权限&#…

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

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

virtualbox安装的linux虚拟机安装并启动Tomcat过程(结合idea操作)记录,并使用宿主机访问页面

virtualbox安装的linux虚拟机安装并启动Tomcat过程&#xff08;结合idea操作&#xff09;记录&#xff0c;并使用宿主机访问页面 参考教程地址linux版本Tomcat下载地址上传解压 启动TomcatVirtualBox虚拟机本地可访问宿主机尚未可以访问关闭防火墙宿主机可以访问 参考教程地址 …

构建自己的物料解决方案——构建物料库,实现前端设计

01: 数据拦截简化数据获取流程 /** * 响应拦截器&#xff1a; * 服务端返回数据之后&#xff0c;前端 .then 之前被调用 */ service.interceptors.response.use((response) > {const { success, message, data } response.dataif (success) {return data}// TODO&#xff…

顺序读写函数的介绍:fscanf fprintf

目录 函数介绍&#xff1a; fprintf&#xff1a; 将结构体变量s的成员列表内容写入文件中&#xff1a; 文件效果&#xff1a;已经进行了格式化&#xff0c;3.140000是最明显的效果&#xff0c;因为float需要补齐0来补充精度 和printf的对比&#xff1a; 不同之处&#xff…

基础排序算法

插入排序&#xff08;insertion sort&#xff09; 插入排序每次循环将一个元素放置在适当的位置。像抓牌一样。手里的排是有序的&#xff0c;新拿一张牌&#xff0c;与手里的牌进行比较将其放在合适的位置。 插入排序要将待排序的数据分成两部分&#xff0c;一部分有序&#…

ddd扬帆

简介 读取了一篇“产品代码都给你看了&#xff0c;可别再说不会DDD”较为清晰了解了&#xff1a;领域驱动设计&#xff0c;整洁架构和事件驱动架构的架构思想落地实践&#xff0c;特做记录读后感&#xff0c;可以直接跳到正文阅读原文 正文 以下正文... 构建自己的软件大厦 …

【C++】C++11——可变参数模板和emplace

可变参数模板的定义方式可变参数模板的传值计算可变参数模板参数个数参数包展开方式递归展开参数包逗号表达式展开参数包 emplace插入 可变参数模板是C11新增的最强大的特性之一&#xff0c;它对参数高度泛化&#xff0c;能够让我们创建可以接受可变参数的函数模板和类模板。 在…

(a)Spring注解式开发,注册组件的@Repository,@Service,@Controller,@Component使用及说明

注解扫描原理 通过反射机制获取注解 Target(value {ElementType.TYPE})// 设置Component注解可以出现的位置&#xff0c;以上代表表示Component注解只能用在类和接口上 Retention(value RetentionPolicy.RUNTIME)// 设置Component注解的保持性策略&#xff0c;以上代表Comp…

社区团购美团和多多买菜小程序购物车

概述 微信小程序购物车列表demo 详细 需求 显示食物名称、价格、数量。 点击相应商品增加按钮,购买数量增加1,点击食物减少按钮,购买数量减一 显示购买总数和总金额 查看当前购买的商品 效果图(数据来自本地模拟) 目录结构 实现过程 主要wxml <view classfoods>…

工具篇 | H2数据库的使用和入门

引言 1.1 H2数据库概述 1.1.1 定义和特点 H2数据库是一款以 Java编写的轻量级关系型数据库。由于其小巧、灵活并且易于集成&#xff0c;H2经常被用作开发和测试环境中的便利数据库解决方案。除此之外&#xff0c;H2也适合作为生产环境中的嵌入式数据库。它不仅支持标准的SQL…

饮料生产线Modbus协议转换网关的应用介绍

在饮料生产线设备数据采集和控制系统中&#xff0c;MODBUS网关是一种非常重要的设备。它可以将不同设备之间的通讯协议转换为统一的MODBUS协议&#xff0c;从而实现数据采集和指令下达。在本文中&#xff0c;我们将介绍如何使用MODBUS网关采集饮料生产线设备数据并下达指令。 在…

知识库搭建保姆级教程,如何从0到1完成知识库搭建

在这个信息爆炸的时代&#xff0c;如何获取、整理和应用知识成为了我们个体价值和企业核心竞争力打造的重要表现&#xff0c;搭建一个高效的知识库可以提升我们企业的竞争力&#xff0c;必要时还能快速切换赛道&#xff0c;开展一个新的领域。 今天我们将结合HelpLook 来与你一…

基于C++实现的3D野外赛车驾驶游戏源码+项目文档+汇报PPT

项目介绍&#xff1a;本项目实现了一个户外场景下的赛车游戏&#xff0c;可以通过键盘控制赛车的移动&#xff0c;视角为第二人称视角。场景中有汽车&#xff0c;建筑&#xff0c;道路&#xff0c;天空等物体&#xff0c;拥有光照和阴影的效果。通过粒子系统模拟尾气效果&#…

Kubernetes组件和架构简介

目录 一.概念简介 1.含义&#xff1a; 2.主要功能&#xff1a; 3.相关概念&#xff1a; 二.组件和架构介绍 1.master&#xff1a;集群的控制平面&#xff0c;管理集群 2.node&#xff1a;集群的数据平面&#xff0c;为容器提供工作环境 3.kubernetes简单架构图解 一.概…

Windows迁移文件的快速方法

文章目录 1.简单比较2.传输方法介绍&#xff1a;有线&#xff08;直连网络&#xff09;3.传输方法介绍&#xff1a;无线热点传输4. 共享文件夹的设置5.挂载共享文件夹 1.简单比较 方法传输速度有线传输接近900Mb无线热点传输接近500MbU盘传输基本上不超过100Mb 2.传输方法介绍…

小程序-uniapp:URL Link / 适用于在移动端 从短信、邮件、微信外网页 等场景打开小程序任意页面

一、背景介绍 小程序URL Scheme、URL Link是微信小程序后台生成的一种地址&#xff0c;适用于从短信、邮件、微信外网页 等场景打开小程序任意页面。所以&#xff0c;适用性极强。可与微信扫码携带参数跳转到小程序指定页面技术互补 若在微信外打开&#xff0c;用户可以在浏览…

【C++】C++ 类中的 this 指针用法 ③ ( 全局函数 与 成员函数 相互转化 | 有参构造函数设置默认参数值 | 返回匿名对象与返回引用 )

文章目录 一、全局函数 与 成员函数 相互转化1、成员函数转为全局函数 - 多了一个参数2、全局函数转为成员函数 - 通过 this 指针隐藏操作数 二、有参构造函数设置默认参数值三、返回匿名对象与返回引用四、完整代码示例 一、全局函数 与 成员函数 相互转化 1、成员函数转为全局…

2023-Chrome插件推荐

Chrome插件推荐 一键管理扩展 链接 https://chromewebstore.google.com/detail/lboblnfejcmcaplhnbkkfcienhlhpnni 介绍 一键开启、禁用Chrome插件。 Checker Plus for Gmail™ 链接 https://jasonsavard.com/zh-CN/Checker-Plus-for-Gmail https://chromewebstore.goo…