昨天才开始正经地接触Python,以前都是白嫖别人写好的程序。
好吧,其实现在也依然没有正经地系统性学习,学会什么算什么吧。
关于这个像我一样毫无意义的小爬虫:
爬取BiliBili首页的标题和描述,保存.txt文档到本地
爬取img标签里的图片url保存到本地,下载url对应的图片到本地
(要写爬虫就要分析网页的源代码嘛,结果分析着分析着,我点进了首页推荐的沙雕视频,然后沉溺进了更多的沙雕视频,人都笑没了......所以一定要学会拒绝诱惑hhhhhh)
知识点
1.获取网页源代码
2.文件的读写
3.字符串的增删改查
4.通过正则表达式从源代码里过滤数据
源代码
透着浓浓智障气息的原始版本:
import re
import requests
# 通过url获取到网页源代码
url = "https://www.bilibili.com/"
response = requests.get(url)
# 指定编码方式
response.encoding = "utf-8"
# 保存为text
btext = response.text
# "title":"【花呗、借呗,你不知道的】全网疯转的视频,首发在此"
# "desc":"这个10月30号的视频,…”"
# 写正则表达式
title = re.compile(r'"title":"(.*?)"')
desc = re.compile(r'"desc":"(.*?)"')
# 创建列表,将获取到的数据存放进列表
blist = []
for j in desc.findall(btext):
# 先存放title,再存放desc
for i in title.findall(btext):
blist.append("标题:"+i)
blist.append("简介:"+j)
# 创建文档并将blist里的数据写入其中
# 忽略错误
with open("../Python学习/title&desc.txt", "w+", errors='ignore') as f:
f.write("\n".join(blist))
f.close()
# <img src="https://..."
# 写获取图片的正则表达式
img = re.compile(r'<img src="(.*?)"')
# findall返回的数据类型是一个列表
# 获取所有的图片url
imgurl = img.findall(btext)
# 创建文档并将图片的url写入文档
with open("../Python学习/imgurl.txt", "w+") as f:
f.write("\n".join(imgurl))
f.close()
# 由于获取到的图片,有的以https://开头,有的没有
# 所以处理一下这个问题
urldata = ""
# a+:追加读写、不覆写
with open("../Python学习/imgurl.txt", "a+") as f:
# 每次打开的时候将指针挪到初始
f.seek(0)
# 按行读取文原文档内容
linelist = f.readlines()
# 先将文档清空,方便后面写入
f.truncate()
# 做一个判定:
# 如果原来的url自带https://,略过此行
# 如果没有,就在行前追加https://
for line in linelist:
regex = re.compile(r'https://')
# match()只匹配一次且仅仅匹配开头
# 就是123与12345能匹配成功
if regex.match(line):
newline = line
else:
newline = "https:"+line
urldata += newline
f.close()
# 将整理好的urldata写入文档
with open("../Python学习/imgurl.txt", "w+") as f:
f.write(urldata)
f.close()
# 最后下载图片
# 以列表的形式打开修改过后的文档
# 先声明一个列表
urllist = []
# 打开文件
with open("../Python学习/imgurl.txt", "r") as f:
# 搞掉换行符\n
for line in f.readlines():
line = line.replace("\n","")
urllist.append(line)
f.close()
# 再整个参数
i = 0
for iurl in urllist:
# 用二进制解析图片
# 超过五秒,失去耐心
img = requests.get(iurl,timeout = 5).content
if img:
with open(str(i)+".jpg","wb") as f:
print("第"+str(i+1)+"张图片下载ing..." )
f.write(img)
i +=1
else:
print("下载失败,略~~~")
终于终于终于把这个毫无意义的东西成功写出来运行了!!!
但是,我为什么要把图片的url存放进列表里,
再创建txt文档,
再把文档里的图片url拿出来重新放进列表拿出来用。
我这不就是有毛病么......为什么不直接在存进第一个列表以前,做出判定,然后美滋滋地用现成的列表呢?
改造升级了一下,于是有了现在这个——
还是看起来不太聪明的升级版本:
import re
import requests
# 通过url获取到网页源代码
url = "https://www.bilibili.com/"
response = requests.get(url)
# 指定编码方式
response.encoding = "utf-8"
# 保存为text
btext = response.text
# "title":"【花呗、借呗,你不知道的】全网疯转的视频,首发在此"
# "desc":"这个10月30号的视频,…”"
# 写正则表达式
title = re.compile(r'"title":"(.*?)"')
desc = re.compile(r'"desc":"(.*?)"')
# 创建列表,将获取到的数据存放进列表
blist = []
for j in desc.findall(btext):
# 先存放title,再存放desc
for i in title.findall(btext):
blist.append("标题:"+i)
blist.append("简介:"+j)
# 创建文档并将blist里的数据写入其中
# 忽略错误
with open("title&desc.txt", "w+", errors='ignore') as f:
f.write("\n".join(blist))
f.close()
# <img src="https://..."
# 写获取图片的正则表达式
img = re.compile(r'<img src="(.*?)"')
# findall返回的数据类型是一个列表
# 那就先整个列表
urllist = []
# 往里面塞数据
for i in img.findall(btext):
regex = re.compile(r'https://')
if regex.match(i):
continue
else:
i = "https://"+i
i.replace("\n","")
urllist.append(i)
# 创建文档并将图片的url写入文档
with open("imgurl.txt", "w+") as f:
f.write("\n".join(urllist))
f.close()
#这不就完事了么,我刚刚宛如一个智障
# 以列表的形式打开文档
# 先声明一个列表
urllist = []
# 打开文件
with open("../Python学习/imgurl.txt", "r") as f:
# 搞掉换行符\n
for line in f.readlines():
line = line.replace("\n","")
urllist.append(line)
f.close()
# 再整个参数
i = 0
for iurl in urllist:
# 用二进制解析图片
# 超过五秒,失去耐心
img = requests.get(iurl,timeout = 5).content
if img:
with open(str(i)+".jpg","wb") as f:
print("第"+str(i+1)+"张图片下载ing..." )
f.write(img)
i +=1
else:
print("下载失败,略~~~")
欣慰,终于有点进步了。
但是我还有一个很苦恼的问题:
上面的代码是将url存进列表里→写入文档→从文档中读取内容装进列表→从列表里拿url发送请求对吧。
就很.....像一个没用的圈圈
为什么还要构造一个列表来发送请求呢,第一步不是已经有列表了嘛。
但是如果直接使用第一步的列表,就会一直报这个异常:Requests.exceptions.InvalidURL
我再琢磨琢磨。
另外,待会儿解决一下开了fiddler会报一个requests.exceptions.SSLError的问题。