【Python】DAY01学习日记,一个像我一样毫无意义的小爬虫

昨天才开始正经地接触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的问题。

上一篇:使用FormData数据做图片上传: new FormData() canvas实现图片压缩


下一篇:kindeditor修改图片上传路径-使用webapi上传图片到图片服务器