1.urllib
1.1基本使用
1.2 下载(图片,页面,视频)
1.3 get
1.3.1 quote 中文变成对应uncode编码
当url 的wd='中文时' quote是将中文变成对应uncode编码 然后拼接成完整的url
1.3.2urlencode方法 wd有多个参数
1.3.3ajas get实例 爬取豆瓣电影单页
1.因为是get所以才可以用get请求方式,找到含有所有信息的接口
总结:
1.导包
2.url 因为是get所以才可以用get请求方式,找到含有所有信息的接口
3.headers
4.请求对象的设置
5.获取请求相应 6.读要注意编码格式 7.书写,在书写时应该提前查看html是什么格式
1.3.4 多页 写代码需要什么就导入什么包
思路:
1.有十个url ,每个url形成,过程一样所以写入函数
2.,每个ur都要l获取相应,相应中步骤也一样
3.书写,每个url也都要创建一个文件来书写
post一样的思路,重点 url
1.4 post
如果html是josn格式,那么还要
1.5异常一般 try catch
1.5.1 http.error
1.5.2 url.error
1.6 爬取有登录的网站(cookie)
五步骤一样只有headers有改变
①:里面有自己登陆过的信息 重点 但每次登录这个值都会不一样
②:这是从哪个地址访问进来的,图片的反爬会用到
1.6 handler
防止ip禁止封住
1.7 代理 ip+端口号
1.8 代理池
多个代理组成的数组,利用随机数
总结:用代理的时候首先写代理ip,然后才是爬虫的步骤,关键是request后面是代理的三步
2解析
2.1 xpath
不用安装插件
安装lxml库在终端安装即可
运用xpath和requests时遇到的问题
1.html中要注意与网页中network对比
2.2基本语法
总结
urllib(获取网页html)+xpath(解析html)
2.2 josnpath
只能解析本地文件
3.bs4
3.1基本语法
3.1.1安装和能爬的对象
3.1.2节点定位
4.selenium
本身是有界面,既然有界面速度有些慢
Chrome 126-128 chromedriver
https://googlechromelabs.github.io/chrome-for-testing/
4.1元素定位
1.id
2.name
3.xpath
4.tag_name
5.css_selector(bs4)
6.link_text
4.2 获取元素信息和交互
无界无界面的hadless
5.requests
5.1基本使用
5.2get
可以与urllib中get对比 param参数不是必须的如果有像wd=的就用param。
Urllib
5.3post
5.4 代理
快代理上有免费的ip,不一定好使,也可以买一个
就是在ip上做手脚
5.5cookie
案例 爬登录后的古诗词
针对的是有验证码和登录
需求:爬取 登录后的html
攻克的难关:绕过登录(不想输入账户和密码)
分析:验证码,其他的暂时未知
1.首先获取跳转时的url,
思路1正常登录
1.清空日志,点击保留日志
2.正常登录,点击负载可以看到自己登录的信息
2是登录后的1.跳转时的
2.错误登录
不要点击确定否则会跳转到其他页面
确认是什么请求
2.爬虫获取请求(urllib,requests)
因为post请求参数有url,data,headers,
url已经有了,headers也有了,就差设置data(下面的红框里面的除了登录,一般情况下除了账户密码,from,其他的都不知道)
所以接下来就要获取1,2,6
通过多次错误登录查看1和2 的值不会变,看看最初登录url里面有木有 也要看是什么请求(get)
里面有
所以先获取最初的html,然后获取1,2的值(xpth,bs4)
通过bs4用选择器,现根据id找到该标签然后获取value的值
因为select返回的是一个列表所以要用切片拿到列表里面数据
解决1,2后再解决验证码
因为验证码没登录或刷新都会变
最好可以动态的拿取到比如url
然后下载下来
运行程序时可以打开图片手动输入
因为目标是一个html所以要写来了,并打开看看是否成功
因为 访问验证码时会发送一个请求,导致验证码刷新,之后再次访问又会刷新,导致验证码不对
解决办法
reqests里面有一个session方法可以使返回变成对象,要把图片下载下来要用二进制
查看验证码去文件夹里面去看因为运行后目录里面不一定刷新出来也用session.post()
最后成功
企业中一般会用第三方软件识别认证码,提高效能 jiyingwang
6.scripts
当scripts,vrawlspider爬取多页时候 allowed改为域名
6.1安装报错时
6.2项目创建
如果请求额url后面以html结尾不要加/
6.3response基本使用
工作原理
6.4scrapy shell
测试解析代码是否爬到数据(xpath b4)
用的方法在 1.物理机终端安装ipython
2.直接输入 scrapy shell 域名(www.baidu.com)
3.解析
4.查看内容
案例1.当当网爬社会书
1.创建项目以及验证url是否正确
2.在管道中定义有哪些数据需要爬取
3.定位想要爬取东西
4.分析一下结构方便 解析
要爬取的东西都在这个ul下面
5.解析
比如
通过观察 价格有两个xpath路径
Src
通过观察又有问题,查看源代码
所以图片的xpath也有两个,后续写爬虫时要分情况,用if语句即可,
条件分析
都有src,但一个有data-original,一个没有,所以在data-original上做文章
全部完成后
6.书写爬虫
因为每一个都是包含多个所以想要实现一个名字一个price一个图片,所以最好是找到他们共同的部分,再共同的部分接着xpath
共同的部分
所以爬虫可以这样写,并验证一下
因为价格有些是区间,如果也爬下来后面的数据清洗要处理,不爬下来也要处理所以不制造麻烦不爬下来
对于src 都有src,但一个有data-original,一个没有,所以在data-original上做文章
想加序号在爬虫这里加
6.爬取完后就要存储下来pipelines
1.setting中开启一个通道
2.在爬虫文件中导入items定义的类
导入时那两个红色波浪线是表明书写规范,并不影响运行
3.就是items中自己定义的类名
4.书写提交的代码
socialbookitem中参数名称与items定义的参数名称一致
5.在piplines中书写存储代码
总结:
1.不推荐使用with open()因为使用withopen每一次传递对象都会开启一次,影响读取,也会产生覆盖效果
2.xpath不熟悉,不能很快的定位比如爬price时候
扩展1多条管道同时进行
1.定义管道类
2.书写内容
需要注意url是否完整
这里就不完整需要,将他补充完整
这里最好不要手动创建文件夹容易位置错误,最好自动创建文件夹,导下载图片失败致后面
青蓝色是自己手动创建
红色的是自动创建
3.再开启一条通道
模仿上面即可
格式为路径+管道到类名
4.总结
因此,每个管道类中的 process_item
方法名必须相同,
扩展2多页下载
1.针对allowed_domains改动
域名不要https,一般
2.分析每页的URL有什么不同
#第二页
#https: //category.dangdang.com/pg2-cp01.21.12.00.00.00.html
#第三页
#https://category.dangdang.com/pg3-cp01.21.12.00.00.00.html
#第四页
#https://category.dangdang.com/pg4-cp01.21.12.00.00.00.html
3.写代码
utl设置完成后,关键的是如何调用
yield scrapy.Request(url=url,callback=self.parse)
url就是每页的url,callback=(调用的函数名)
扩展3当从一个页面跳转到另一个子页面时可以多次
1.先找到跳转页面的url,要发出请求
2.拿到了,接着发出请求,并验证
跟当当网爬第二页同样的思路,只不过图片xpath在另一个URL后,再次解析
#src=//div[@id='Zoom']//img//@src
https://img9.doubanio.com/view/photo/l_ratio_poster/public/p2910488597.jpg
https://img9.doubanio.com/view/photo/l_ratio_poster/public/p2910208192.jpg
排除一下,因为每次都是不同url,图片的xpath可能会不一样
注意:当黑框能出来但爬不出来,大部分是xpath路经问题,可以对路径删,该
3.如何把第一个的name给到第二个呢
scrapy.reqiest里面有meta可以强制转换成字典
第二个方法接收一下
4.然后上传和导入items方法
5.跟之前一样的在piplines中书写存储代码
如果多条管道也是同样的方法
扩展四链接提取器crawlspider(读书网)
跟scrapy很相似
之前爬多页时是知道最后有多少页,但不知道的时候,可以用
1.创建项目
2.写正则
例如
\d代表数字,+
.有时候不生效所以加个转义 \
观察是从2开始,因为是根据正则表达式,符合的爬,不符合不爬
https://www.dushu.com/book/1188.html这是第一页,并不符合,所以改成一样的 格式
爬多页的时候写域名
3.解析以及结果
图片打不开是正常的
4.其他的一样的提交,存储(写代码),导入,开导管
5.结果
扩展五存入linux中数据库
首先在linux安装mysql
老师给的mysql初始化操作
1.创建好数据库
格式一致
2.准备插入数据前的东西
1.linux虚拟机的ip :192.168.186.129
2.端口号:3306 (是一个整数)
3.user:
4.password:
5.数据库名:crawlspider
6.数据库的字符集:utf8
想用其他暂时只需要该ip,password,数据库名
3.在setting写下准备的东西
utf-8 这里不写-,端口号必须为整数
4.在管道中创建一个,并设置优先级
5.pymysql
如果没有就安装pymysql
这里我本来就有
6.加载settings文件
7.书写连接setting文件
8.写pymysql语句
先导入pymysql,写,最后关闭
9.运行之后的问题
1.权限问题
pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'192.168.186.100' (using password: YES)")
错误信息 pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'192.168.186.100' (using password: YES)")
表示MySQL服务器拒绝了尝试使用用户名 root
和IP地址 192.168.186.100
进行登录的请求。这通常是因为以下几个原因:
1.检查用户权限:确保数据库用户 user1
有权限从 IP 地址 192.168.186.100
访问数据库。这通常在 MySQL 中通过 GRANT
语句完成。你可能需要联系数据库管理员或检查 MySQL 的用户表来确认这一点。
你需要登录到 MySQL 数据库,检查 'user1' 的权限设置。可以使用以下 SQL 命令查看用户权限:
SELECT user, host FROM mysql.user WHERE user = 'user1';
发现没有用户
2.mysql密码设置问题 创建用户显示
解释:
你尝试设置的密码不符合MySQL的密码策略要求。MySQL有一组密码强度验证规则,以确保密码足够强大,难以被猜测或破解。
通过以下命令查看密码规则 SHOW VARIABLES LIKE 'validate_password%';
显示:
Variable_name | Value |
+--------------------------------------+--------+
| validate_password_check_user_name | OFF | 是否包含用户名 on:不能包含用户名 off:可以包含
| validate_password_dictionary_file | | 如果它是一个空值,表示没有使用外部字典文件来检查密码。
| validate_password_length | 8 | 最小长度
| validate_password_mixed_case_count | 1 | 必须包含的不同大小写字母的最小数量 设置为1
意味着密码至少需要包含一个大写字母和一个小写字母。
| validate_password_number_count | 1 | 必须包含的数字的最小数量
| validate_password_policy | MEDIUM |
-
这个变量设置密码的验证策略强度。可能的值包括:
-
LOW
:只检查密码长度。 -
MEDIUM
:检查密码长度、混合大小写字母、数字和特殊字符。 -
STRONG
:除了MEDIUM
的所有检查外,还检查密码是否在字典文件中。
-
| validate_password_special_char_count | 1 | 这个变量设置密码中必须包含的特殊字符的最小数量。
+--------------------------------------+--------
我创的用户名密码:GRANT ALL PRIVILEGES ON crawlspider.* TO 'user1'@'192.168.186.100' IDENTIFIED BY ' 自己设';
3 检查MySQL用户权限
确保MySQL用户user1
有权限从192.168.186.100
访问数据库。可以通过以下SQL命令检查和修改用户权限:
-- 检查用户权限 SELECT User, Host FROM mysql.user WHERE User = 'user1';
检查用户具体权限 SHOW GRANTS FOR 'user1'@'localhost';
-- 如果权限不正确,可以重新设置权限 GRANT ALL PRIVILEGES ON crawlspider.* TO 'user1'@'192.168.186.100' IDENTIFIED BY 'B@d2202daifulin';
解释 ALL PRIVILEGES 表示授予所有可能的权限,这包括但不限于SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER等。
ON crawlspider.*:
ON 关键字后面跟着指定权限应用的范围。
crawlspider.* 表示这些权限将被授予crawlspider数据库中的所有表(* 是通配符,代表所有表)。
TO ‘user1’@‘192.168.186.100’: TO 关键字后面跟着指定的用户和主机。
'user1' 是被授予权限的用户名。
'192.168.186.100' 是允许该用户连接到MySQL服务器的主机IP地址。这意味着只有从IP地址192.168.186.100发起的连接才会使用这些权限。 IDENTIFIED BY ‘bd2202daifulin’: IDENTIFIED BY 关键字用于设置用户的密码。
' ' 是用户user1的新密码。
FLUSH PRIVILEGES; 解读: 在执行了任何修改权限的命令后,都应该执行 FLUSH PRIVILEGES; 命令,以确保所做的更改能够立即生效,而无需重启MySQL服务器
权限解读:
User: user1
这表示数据库中存在一个用户名为user1
的用户账
请注意,USAGE
权限本身并不授予对任何数据库或表的访问权限,它只是表示登录权限。实际的权限(如SELECT
, INSERT
, UPDATE
, DELETE
, CREATE
, DROP
等)必须明确地授予。如果你没有看到SHOW GRANTS
命令的输出,那么可能意味着user1
没有分配任何权限,或者仅有基本的登录权限。
-
Host:
localhost
-
这表示
自己的use
r1
账户只能从本地主机(即运行MySQL服务器的主机)进行连接。如果这里的值是%
,则表示user1
可以从任何主机连接到MySQL服务器 -
更全的展示:
-
USAGE ON
.
TO 'user1'@'
localhost
'
表示user1
用户有权限登录到MySQL服务器,但没有指定数据库的任何操作权限。 -
GRANT SELECT, INSERT, UPDATE ON
mydatabase.* TO 'user1'@'
localhost
'
表示user1
用户在mydatabase
数据库上有SELECT
,INSERT
, 和UPDATE
权限。
4. 检查MySQL配置
确保MySQL服务器配置允许从192.168.186.100
进行访问。检查MySQL的my.cnf
或my.ini
配置文件中的bind-address
设置,确保它允许远程连接。 一般位置:
基于Debian和Ubuntu的发行版:
-
/etc/mysql/mysql.conf.d/mysqld.cnf
-
或者
/etc/mysql/my.cnf
基于Red Hat、CentOS和Fedora的发行版:
-
/etc/my.cnf
-
/etc/mysql/my.cnf
-
或者
/etc/my.cnf.d/mysql-server.cnf
进入后会看到
。bind-address默认情况下,它被设置为 127.0.0.1
,这意味着MySQL服务器只接受来自本地主机的连接。如果你想允许远程连接,可以将这个值更改为服务器的公共IP地址或者设置为 0.0.0.0
以监听所有网络接口。
设置完后要重启mysql服务:
3.mysql服务问题
systemctl restart mysql
如果启动时显示:
解决思路:
检查服务名称
查看所有已安装的服务:
systemctl list-unit-files --type=service
找到与mysql有关的:
第二个是表示:它表示一个模板服务单元,用于创建实例化的服务单元。
如,如果你想启动两个MySQL服务实例,每个实例监听不同的端口,你可以这样做:
bash
systemctl start mysqld@instance1.service
systemctl start mysqld@instance2.service
在这里,instance1
和 instance2
是实例的名称,它们可以根据需要自定义。每个实例将根据 mysqld@.service
模板创建,但具有自己的特定配置,如不同的端口、数据目录或其他设置
5检查数据库服务状态:确保数据库服务正在运行,并且监听在正确的端口上。你可以使用命令 mysqladmin ping
或 netstat -an | grep 3306
来检查服务状态。
解读:
-
tcp:这表示连接使用的是 TCP(传输控制协议)。
-
0:这是发送队列中的字节数。由于这里显示为 0,这意味着当前没有数据在发送队列中等待发送。
-
0:这是接收队列中的字节数。同样,0 表示接收队列中没有数据等待处理。
-
0.0.0.0:3306:这表示 MySQL 服务器正在监听所有可用的网络接口上的端口 3306。
0.0.0.0
是一个特殊的 IP 地址,代表所有可用的 IP 地址(即服务器上的所有网络接口)。 -
0.0.0.0:*:这表示 MySQL 服务器准备好接受来自任何 IP 地址的连接。星号
*
表示对任何远程 IP 地址和端口的监听。
所以: MySQL 服务器正在运行,并且正在监听所有网络接口上的端口 3306,准备接受来自任何远程主机的连接请求
-
LISTEN:这表示 MySQL 服务器正在监听状态,准备好接受进入的连接请求。
6检查网络连接:确保从你的 Scrapy 爬虫运行的机器到数据库服务器的网络连接没有问题。你可以使用 ping
或 traceroute
命令来测试网络连
ping <数据库服务器IP>,traceroute <数据库服务器IP>
数据库服务ip就是bind-address 的值
如果bind-address=0.0.0.0就不是这个值
只能查看
linux:
如果你的数据库服务器和Scrapy爬虫在同一台机器上
hostname -I
当前机器的所有网络接口的IP地址
ifconfig或ip addr
展示:
3检查防火墙设置:确保没有防火墙规则阻止了从 Scrapy 爬虫运行机器到数据库服务器的连接
windows打开“控制面板”,然后选择“系统和安全”>“Windows Defender 防火墙”,在Windows防火墙的高级设置中,你可以查看或编辑入站规则。确保3306端口有一个允许的规则。
4.字符集问题
运行后出现的问题:
SQL error: (1366, "Incorrect string value: '\\xE6\\x9C\\x9D\\xE6\\x9E\\x9D...' for column 'name' at row 1") 这个错误是由于字符集或编码问题引起的。
解决办法
检查数据库和表的字符集
确保您的数据库和表都使用的是utf8
或utf8mb4
字符集。utf8mb4
是一个更好的选择
数据库
SELECT DEFAULT_CHARACTER_SET_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME = 'crawlspider';
结果
查找特定表
SHOW FULL COLUMNS FROM crawlspider.book;
该表中name,src 字符集为utf-8(scrapy setting设置好了的)
之后检查是否成功存入
综上所述:
在写完scrapy之后
1.mysql是否安装
2.mysql是否创建用户和用户权限,特别注意创建用户时密码要求,用户是否允许从哪些登录
3.mysql配置是否能被其他访问
4.mysql服务状态
5.网络连接
6.创建数据库和表的时候要注意格式和每个字段的字符集
扩展六日志信息及日志级别
在settings里面写