着手写爬虫前,需要了解的几个概念:
URL
全称 Uniform Resource Locator (统一资源定位器),格式为:协议+主机+端口+路径。
比如:https://www.bilibili.com/video/BV17x411w7KC
https:// 是协议,www.bilibili.com 是主机域名,这个例子中端口号并未在主机域名后指定,使用的是默认端口,/video/BV17x411w7KC 是文件路径。
简单来说,就是使用浏览器打开一个网页时,显示在最上方搜索栏中的内容。
正则表达式
通过使用一些预设的字符来创建的通常用于检索字符串的具有一定规则的文本。
需要掌握基本的用法。
比如这个正则表达式:a(.*?)z
可以匹配的字符串有:“abz”,“ab123z”,“ab123字符串z”。
除了以上三种,只要字符串满足第一个字符是 ‘a’,最后一个字符是 ‘z’,都可以被这个正则表达式匹配。因为表达式中的 (.*?) 表示匹配任意字符串。
爬虫
自动从网页上抓取数据的程序或者脚本。
为什么需要爬虫?
试想一下,当你在某壁纸网站闲逛时,发现一个分栏下的壁纸都很好看,想要将他们都下载下来,如果手动操作的话,你需要一张一张地点击下载,而如果使用爬虫,你则可以运行爬虫,然后冲一杯咖啡,稍等片刻,壁纸就都已经下载并保存到你的文件中了。
了解了基本的概念,再来了解爬虫的基本流程。
爬虫的三个主要流程:
(1)请求
向服务器发送请求,并得到服务器响应后返回的数据。
(2)匹配
对返回的数据使用正则表达式进行处理,匹配出需要的内容。
(3)保存
匹配出的内容通常为资源链接,我们通过解析该链接并发送请求,将获取到的数据保存到本地。
OK,开始写爬虫吧。
本次目标:爬取B站首页热门推荐视频标题
首先,我们需要导入必要的模块
#HTTP请求
import urllib
import urllib.request
#正则表达式
import re
#文件
import os
然后,我们依次实现爬虫的三个流程:
请求:
浏览器请求头需要我们进入网站按 f12 获取。
#发送请求并返回获取到的HTML数据(字符串)
def GetHTML(url):
#伪装浏览器请求头
header = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 Edg/87.0.664.75'}
#使用传入的url创建一个请求
request = urllib.request.Request(url, headers = header)
#发送请求并得到响应
response = urllib.request.urlopen(request)
#获取通过utf-8格式解码后的HTML数据
HTML = response.read().decode('utf-8')
#返回HTML数据
return HTML
匹配:
正则表达式需要进入网站按 f12 定位到想要爬取的资源,根据资源的属性写出对应的正则表达式。
#从HTML数据中匹配出所有标题
def GetTitles(HTML):
#通过正则表达式创建一个正则匹配模式
pattern = re.compile('<p.*?class="title">(.*?)</p>')
#得到所有匹配结果,findall的返回值类型为列表
titles = re.findall(pattern, HTML)
#返回所有标题内容
return titles
保存:
#将数据保存到文件
def SaveData(data):
#判断一个文件夹是否存在
flag = os.path.exists('title')
if not flag:
#不存在则新建一个文件夹
os.mkdir('title')
print('文件夹','title','创建成功')
else:
print('文件夹','title','已存在')
#将列表中的数据写入文件并保存在文件夹中
i = 0
for title in data:
#打开文件时在文件名前加上文件夹路径
file = open('title/'+'标题'+str(i)+'.txt', 'w')
file.write(title)
file.close()
print('标题',str(i),'写入成功!')
i += 1
欧克,调用函数运行一下:
#发送请求并获取数据
HTML = GetHTML('https://www.bilibili.com/')
#匹配出我们需要的数据
titles = GetTitles(HTML)
#将数据保存到本地
SaveData(titles)
#暂停一下
pause = input('任意键退出')
运行效果:
其他类型的资源的爬取思路相同,感兴趣的小伙伴赶快试试吧~