持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天, 点击查看活动详情
本文主要介绍了爬虫相关的入门知识。
本文目录
爬取小猫的图片
- 写入文件相关
- 正则表达式简介
- bs4解析
前言
关于爬虫的书籍:
Python爬虫书籍--崔庆才著(第一版)
阿里云盘获取,2025年失效
这本书已经出版第二版了,有能力的大可去购买正版书籍去支持~
爬虫常用框架介绍:
1.scrapy框架
2.pyspider
3.cola框架(分布式)
爬虫第一步
我们先熟悉爬虫的大致步骤:确定目标网址 -> 请求该网址 ->读取response -> 处理response -> 写入文件/...
下面以爬取一张小猫的图片为例,让我们来一起走通整个流程~
首先是引入包,爬取小猫的图片需要用到urllib
包,如果你尚未下载,请在terminal先执行pip install urllib -i https://pypi.tuna.tsinghua.edu.cn/simple
来安装此包。
然后引入即可import urllib.request
如果你对镜像操作尚且不熟悉的话,请先浅浅的阅读一下我的上一篇文章
「Python」pip /conda之镜像操作篇
接下来需要确定目标网址,这里直接将目标网址给出来了
url = 'http://placekitten.com/g/500/600'
然后利用request中的urlopen
方法向服务器发送请求,并用resp
变量来接收返回的请求。
resp = urllib.request.urlopen(url)
接下来直接读取resp的内容
cat_img = response.read()
最后打开文件,将小猫的图片保存即可。
with open('cat.jpg','wb') as f:
f.write(cat_img)
整个爬取图片的代码汇总如下:
import urllib.request
url = 'http://placekitten.com/g/500/600'
resp = urllib.request.urlopen(url)
cat_img = resp.read()
with open('cat.jpg','wb') as f:
f.write(cat_img)
爬取的内容:
关于urllib的其他方法,解释如下:
urlopen(string) # 返回一个Object
urllib--URL handing modules
urllib.request for opening and reading URLs
urllib.error containing the exceptions raised by urllib.request
urllib.parse for parsing URLs
urllib.robotparser for parsing robots.txt files
关于写入文件
细心的伙伴一定发现了,上面总体代码中with open()
中wb
是个什么玩意?
w
就是write
的意思,b
一般表示为byte
,即字节。wb
一般用于读写二进制文件。
其他的模式汇总如下:
r : 读取文件,若文件不存在则会报错
w: 写入文件,若文件不存在则会先创建再写入,会覆盖原文件
a : 写入文件,若文件不存在则会先创建再写入,但不会覆盖原文件,而是追加在文件末尾
rb,wb: 分别于r,w类似,但是用于读写二进制文件
r+ : 可读、可写,文件不存在也会报错,写操作时会覆盖
w+ : 可读,可写,文件不存在先创建,会覆盖
a+ : 可读、可写,文件不存在先创建,不会覆盖,追加在末尾
接下来介绍的就是正则表达式了,相信大家对于这个名字一定不陌生,正则表达式的作用一般用于网页信息的提取。也就是在向服务器发送请求之后拿到页面的
text
之后,对其进行信息的提取。
正则表达式
这里推荐一个在线测试正则表达式的网站,可以在线测试自己的想法是否正确。毕竟像我这种正则老是写不对的人来说,真的比较友好了
正则表达式的相关符号
. 匹配除换行以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
\W 匹配非字母或数字下划线
\D 匹配非数字
\S 匹配非空白符
a | b 匹配字母a或字符b
() 匹配括号内的表达式
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
量词:控制元字符出现的次数
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配 && 惰性匹配
.* 贪婪匹配
.*? 惰性匹配
惰性匹配举例
b站弹幕爬取
❗奇淫技巧:https://comment.bilibili.com/760503518.xml 弹幕获取接口
(一个固定的url地址 + 视频的cid + .xml)
参考链接
在bilibili前面加一个小写字母i就会看到该视频的弹幕api
好像是别人写好的东西,但是我并没有找到他弹幕那个链接...不会找。。。
然后F12键就能切换成手机版的,有时候手机版的可能对抓包来说更友好一些。
然后结合正则表达式获取一下弹幕,这里弹幕都是放在<d></d>
标签中,使用<d p=".*?">(.*?)</d>
就可以获取到弹幕信息了~
下面是周董最伟大的作品的弹幕爬取,代码如下:
import requests
url = 'https://api.bilibili.com/x/v1/dm/list.so?oid=765060141'
res = requests.get(url)
res.encoding = 'utf-8'
result = res.text
word_list = re.findall('<d p=".*?">(.*?)</d>', result)
with open('greatest_works_danmu.txt', mode='a', encoding='utf-8') as f:
for word in word_list:
f.write(word + '\n')
analysis_greatest_works.py =>分析周董最伟大的作品源代码(主要是绘图)bvid是b站新的视频唯一标识符,由12位数字、字母组成,大小写敏感,传入时请包含头部的“BV”
比如:“BV1gC4y1h722”
豆瓣电影信息爬取
下面以豆瓣电影界面的信息解析为例,比如我们需爬取电影的名称,评分以及评价的人数。
然后观察一下页面的源代码,发现我们需要的信息包含在一个<li></li>
标签里面,具体的位置信息如下图所示:
评分的信息在一个<div class="star">
里,在使用正则表达式的时候可以把自己想要提取的信息变为(?P<xxx>.*?)
,比如这里将评分的9.7
变为了(?P<score>.*?)
就可以想成一个模板,把爬取的信息改为(?P<xxx>.*?)
就行,<>
之中的名字是自己取的。
整体的正则表达式如下:
# 解析数据
obj = re.compile(r'<li>.*?<div class="item">.*?<span class="title">(?P<name>.*?)</span>'
r'.*?<p class="">.*?<br>(?P<year>.*?) .*?<span class="rating_num" '
r'property="v:average">(?P<score>.*?)</span>.*?'
r'<span>(?P<num>.*?)人评价</span>',re.S)
一般来说,对于初学者,正则表达式的掌握比较的困难,所以上面的没看懂也并没有什么很大的关系。
接下来介绍bs4解析方法,
BS4解析
使用之前必然是先安装库,可以使用一下安装代码安装bs4解析库。
pip3 install Beautifulsoup4
安装
注意这里引入bs4的的代码如下(初学者往往会出错):from bs4 import BeautifulSoup
在前面向服务器发送请求的使用的是urllib.urlopen()
方法,下面使用另外一个包requests
来模拟向服务器发送请求。使用方法和urllib.urlopen()
相似。
使用import requests
导入包,使用requests.get(url)
就可以拿到返回的数据。resp.encoding = 'utf-8'
可以设置网页的编码方式,一般在网页的源代码的头部会标明编码方式。(这种一般是为了防止返回的中文的乱码。
bs4解析的方式也比较的简单易懂。直接对返回的页面源代码进行解析即可。
main_page = BeautifulSoup(resp.text, "html.parser")
上述代码resp.text
就是页面源代码。"html.parser"
是指定text的内容为html形式。
下面以爬取一张壁纸为例,重点介绍一下bs4解析的用法。
通过main_page.find()
方法就可查找页面中的元素了,比如main_page.find("div", class_="TypeList")
,就是查找class="TypeList"的div盒子。这里class加上了_
,好像是因为和关键字重合了,所以加上_
以示区分。
对于页面中的链接a
,我们知道链接一般都有一个属性href
,这个时候当我们拿到<a></a>
的时候,我们想取到这个标签里面的href
属性值。只需要通过a.get("href")
就可以拿到href属性里面的值。
然后整体的爬取壁纸的流程代码如下:
可能壁纸连接失效了,但是整个爬取照片的流程是类似的,这里就不再做修改了)
import requests
from bs4 import BeautifulSoup
url = "https://umei.cc/bizhitupian/weimeibizhi/" # 2022/4/11链接失效了
resp = requests.get(url)
resp.encoding = 'utf-8'
main_page = BeautifulSoup(resp.text, "html.parser")
alist = main_page.find("div", class_="TypeList").find_all("a")
for a in alist:
href = "https://umei.cc" + a.get("href") # 直接通过get就可以拿到属性的值
# print(href)
# 拿到子页面的源代码
child_page_resp = requests.get(href)
child_page_resp.encoding = 'utf-8'
child_page_text = child_page_resp.text
# 从子页面中拿到图片的下载路径
child_page = BeautifulSoup(child_page_text, "html.parser")
p = child_page.find("p", align="center")
img = p.find("img")
print(img.get("src"))
注意上面的print(href)
如果不拼接的话拿到的是:/bizhitupian/weimeibizhi/225260.htm
这种,并不是视频中完整的一个链接。
所以这里需要拼接得到图片的链接地址,不然就在request.get(href)
就会报错,因为request
解析的需要是一个url,但实际上拿到的href并不是一个完整的URL,而是:
报错截图如下:
当遇到报错的时候往往别心烦意乱,慢慢来,一点点排查就能解决了~这里提供一个小的tips:
当下载文件较多的时候,建议将放下载资源的文件夹设置成红色的;设置方式如下:
右击文件夹->Make Directory as -> Excluded即可。
本期的爬虫知识简介就到这了~,后续接着更新⛷️⛷️⛷️
往期好文推荐🪶
「MongoDB」Win10版安装教程