第二阶段 python的操作和 爬虫之各种补充


人生鸡汤
对快感上瘾,是成年人最大的毒药

BeautifulSoup

四种对象

在这里插入图片描述

知识点1 方式(文件类型,“解析器”)

1.open(". /baidu.html",“rb”) rb代表读取二进制
html=file. read( )//读取方式
bs是一个对象,然后我们用BeautifulSoup这个方式来解析,解析的文件类型有很多种,那么你要明确用蛇魔类型,
so 【】 方式(文件类型,“解析器”)【】知识点1在这里插入图片描述

知识点 2 Tag标签

在这里插入图片描述
在这里插入图片描述

平常我们常用的是beautifulsoup//整个文档,tag标签,string。
在这里插入图片描述

遍历文档树


遍历文档树

不只有content是,还有很多其他遍历文档树。详见上方。
文档的搜索
1.find-all()

from bs4 import BeautifulSoup
"""
唯一的差别在于“B”“S”两个字母一定要大写。这就是学东西的时候痛苦和快乐的源头,发现问题并解决问题

"""

file=open("./新建文本文档.html","rb")
html=file.read().decode("utf-8")
bs=BeautifulSoup(html,"html.parser")

print(bs.a)
print(bs.head)
print(type(bs.title))#标签,而且只提取相同类型标签的第一个
print(bs.title)
print(bs.title.string)#只要里面的内容
print(bs.a.attrs)#这是属性,那么他以字典形式保存,键然后是内容。方便
#搜索
print(bs.head.contents)#输出的结果不再是标签,而是列表
print(bs.head.contents[1])


#遍历
#   字符串过滤,会查找与字符串完全相同的内容
list=bs.find_all("b")
 print(list)

#正则表达式:利用search()来搜索
 import re
 t_list=bs.find_all(re.compile("a"))
 print(t_list)


#传入一个函数(方法),根据函数的要求来搜索(了解)
def name_is_exists(tag):
    return  tag.has_attr("name")

t_list=bs.find_all(name_is_exists)


亮汤续集
怎么说呢,还有一些常见的搜索方式。
text文本索引,limit抽取前几个,select方式就更多了。

#1 kward 参数
#2 text 函数


#
# t_list=bs.find_all(text=re.compile("/d"))#使用正则表达式带搜素数字
t_list=bs.find_all(text="douban.com")
for item in t_list:#列表的遍历
    print(item)
3 limit参数

t_list=bs.find_all("a",limit=3)#只提取前limit个列表
for item in t_list:#列表的遍历
    print(item)

# #4.css编译器
t_list=bs.select('title')#使用标签查找

t_list=bs.select('.mnav')#使用类名查找
t_list=bs.select('#u1')#使用id查找
t_list=bs.select("a[target='_blank']")#使用属性查找
t_list=bs.select('span>a',limit=4)#使用子标签查找 一层一层往下走
t_list=bs.select('.mnav~ .bri') #是类别一样在一个层次,也就是一个大标签里面,兄弟节点
#
for item in t_list:#列表的遍历
    print(item)

Python 代码调试技巧

re正则表达式的补充

说白了,正则表达式就是一种字符串模式,判断一个字符串是否符合这种标准
在这里插入图片描述
在这里插入图片描述
图片hheh
匹配模式
匹配模式
在这里插入图片描述

import re
sui=re.compile("AA")#此处的AA代表正则表达式,
# j=sui.search("aaAAAAAxsah")#此处的内容为被校验的内容
j=sui.search("AAaaAAAAAxsah")
print(j)
#总之先用compile生成这样一个对象,然后用search的方式比对。

print(re.findall("a","hasasaakskk"))#前面是正则表达式,后面是被校验的内容  findall
print(re.findall("[A-Z]","haSAASAsasaakAAskk"))
print(re.findall("[A-Z]+","haSAASAsasaakAAskk"))


#sub
print(re.sub("b","B","bhkaskhdahadjbdj"))#把b换成B。常用于将/n换成空白,符号转换

m=r"\\dd\'dwwi\da"
print(m)
print("m")

然后值得注意的是,被比较的字符串前面加上r,就不用担心转义字符的问题了。而且,
m是变量,
“m”是字符串,打印出的东西不一样

史上最全常用正则表达式大全

作者说  大変ですね!
*正则提取这里我快要疯了,一上午在处理这个问题。问百度,百度没有,靠自己,自己存在知识盲区,对这个错误不了解,问别人,一个人被我问烦了。哭了。伤心,不过经过短暂的伤心之后,重新振作,全面解决两个大问题,一直困扰着我,这世上的Q也太多了,真的是活到老学到老。又问了一个学长,才得以解决。不容易死了。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

后来在别人的帮助下,我发现在link=findall运行时,还没有运行到findlink被定义的地方,自然要出错。再就是Ctrl+鼠标左键点击函数的名字,就可以看到他的函数体了

findall函数 正则表达式
在这里插入图片描述
item 内容项目 img图片
re.S为包含换行符,.不包含换行符。所以加上re.s后包含全部字符。

肖申克的救赎

先看前面和后面 r’<img “>’,超链接用src=”(.?),中间杂碎 .代表一个或多个字符,补充换行符。

各种字符规则。吐槽 真是的,这个正则提取今天上午才完结,疯掉,cost so much time

findlink= re.compile(r'<a href="(.*?)">')  # .代表一个字符,*代表0个或多个字符,?代表一次或多次。
#影片图片
findimgsrc=re.compile(r'<img.*src="(.*?)">',re.S)
"""影片图片连接。re.S为包含换行符  常用于超链接这种复杂的东西堆砌,.不包含换行符。所以加上re.s后包含全部字符。
<img width="100" alt="肖申克的救赎" src="https://i-blog.csdnimg.cn/blog_migrate/1517f3c251488a6894c1d0bc4542aa02.webp?x-image-process=image/format,png" class="">
先看前面和后面 r'<img    ">',超链接用src="(.*?),中间杂碎 .*代表一个或多个字符,补充换行符。
"""
#影片名称
findtitle=re.compile(r'<span class="title">(.*)</span>')
#<span class="title">肖申克的救赎</span>
#影片評分
findrating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#<span class="rating_num" property="v:average">9.2</span>
# -* coding=utf-8 *-
#@Time=11:21 
#@Auhor=吴绍冲
#@Name=豆瓣.py
#@Software=PyCharm
#-*- codeing = utf-8 -*-
#@Time: 17:20
#@Author: 吴绍冲
#@File:t2.py
#@sofeware:PyCharm

#引入自定义模块
# from test1 import t1
#
#
# print(t1.add(3,5))
#引入系统模块
import sys
import os
import bs4
import re
import urllib.request
import urllib.error
from bs4 import BeautifulSoup
import csv

findlink = re.compile(r'<a href="(.*?)">')  # .代表一个字符,*代表0个或多个字符,?代表一次或多次。
# # 影片图片
findimgsrc = re.compile(r'<img.*src="(.*?)">', re.S)
"""影片图片连接。re.S为包含换行符  常用于超链接这种复杂的东西堆砌,.不包含换行符。所以加上re.s后包含全部字符。
<img width="100" alt="肖申克的救赎" src="https://i-blog.csdnimg.cn/blog_migrate/1517f3c251488a6894c1d0bc4542aa02.webp?x-image-process=image/format,png" class="">
先看前面和后面 r'<img    ">',超链接用src="(.*?),中间杂碎 .*代表一个或多个字符,补充换行符。
"""
# # 影片名称
findtitle = re.compile(r'<span class="title">(.*)</span>')
# # <span class="title">肖申克的救赎</span>
# # 影片評分
# findrating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')


# <span class="rating_num" property="v:average">9.2</span>

def main():
    url = "https://movie.douban.com/top250?start=0&filter="

    # 1.爬取网页
    datalist = getData(url)
    # print('datalist:', datalist[0])
    savepath = ".//加油.csv"

    askurl("https://movie.douban.com/top250?start=0&filter=")
    # 3.保存数据
    saveData(savepath, datalist)


"""
<a href="https://www.douban.com">模仿这个样子,所以里面是<a href="(.*?)">里面有了双引号,外面加单引号,
里面是单引号,外面是双引号。
"""


# 爬取网页
def getData(url):
    datalist = []
    for i in range(0, 4):  # 调用获取信息的页面10次 一页25条 这个是左闭右开,实际是【0,10)。所以他会得到1-9
        url = url + str(i * 25)
        html = askurl(url)  # 保存获取到的网页源码。接收。。

        """
        0代表第一个网页里的25条,9代表第十个网页。
        """
    file = open("./豆瓣.html", "rb")
    html = file.read().decode("utf-8")
    soup= BeautifulSoup(html, "html.parser")
    for item in soup.find_all("div", class_="item"):  # 不能直接写class,要加下划线
        # print(item)#测试,查看电影item全部信息
        data = []  # 保存一部电影的所有信息
        item = str(item)
        # print(item)

        link = re.findall(findlink, item)[0]  # re库通过用正则表达式查找对应内容
        # print(link)

        data.append(link)
        imgsrc = re.findall(findimgsrc, item)[0]
        data.append(imgsrc)
        titles = re.findall(findtitle, item)
        data.append(titles)
        datalist.append(data)

    # 2.逐一解析数据
    return datalist


# 爬取一个url的信息
def askurl(url):
    headers = {
        "User-Agent": " Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}

    req = urllib.request.Request(url, headers=headers)

    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode("utf-8")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html  # 返回网页代码


def saveData(savepath, savedatas):
    csv_file = open(savepath, 'w', newline="", encoding='utf-8')
    writer = csv.writer(csv_file)
    writer.writerow(["电影"])

    for savedata in savedatas:
        savedata = str(savedata)

        savedata = savedata.replace('/','')
        savedata = savedata.replace('、','')
        savedata = savedata.replace(',','')
        savedata = savedata.replace(' ','\t')
        savedata="".join(savedata.split())
        writer.writerow([savedata])
    print('Save Complete')


if __name__ == '__main__':
    main()


```bash
在这里插入代码片

EXCEL保存

在这里插入图片描述

import  xlwt
workbook= xlwt.Workbook(encoding="utf-8")#创建一个workbook对象
worksheet=workbook.add_sheet('sheet1')#创建工作表
worksheet.write(0,0,'hello')#第一个参数'行',第二个参数'列',第三个参数‘内容’
workbook.save("はじめまして.xls")

注意for

在这里插入图片描述
九九乘法表
在这里插入图片描述

import  xlwt
workbook= xlwt.Workbook(encoding="utf-8")#创建一个workbook对象
worksheet=workbook.add_sheet('sheet1')#创建工作表

for i in range(0,9):
    for j in range(0,i+1):#左闭右开
        worksheet.write(i,j,"%d*%d=%d"%(i+1,j+1,(i+1)*(j+1)))
# worksheet.write(0,0,'hello')#第一个参数'行',第二个参数'列',第三个参数‘内容’
workbook.save("はじめまして.xls")

这里,首先for循环要注意,其次,那个百分号,

%是字符串格式化符号。具体讲就是将其他变量置入到%后面,替换成一个新的字符串。如n=‘cd’
print(‘ab%s’%n) 则显示为abcd

而且是紧跟的%,不能有逗号,%后面紧接着括号
格式 “ 字符串”%( )

Q:strip(),replace()和re.sub()用法

strip(),replace()和re.sub()用法
注释:replace和sub都适用于string

Python正则表达式时出现TypeError: expected string or bytes-like object

Python正则表达式时出现TypeError: expected string or bytes-like object
Q:Debug的好处。断点调试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:汉字,符号,网址等都是字符,不用太过细化
万能(.?)
平常的字符: (.

出现的特殊东西,用re.sub代替就好,记得加对象

小编快累死了 今天一天都在做这个,快累死我了,说实话就是在纠错,烦死了,成年人的世界,满眼辛酸泪。赶紧把辛辛苦苦就出来的错误写下来
O(∩_∩)O哈哈~ 看看 初步成功
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面两张图片反映了一个重大的错误,这些地方原来全部都被我写成url。最重要的是我在主函数里面写了url 而每次都传达给askurl的是url 当然是一直在第一页了。 只有区分baseURL 和url 使url一直更新,才能得到我想要的

SQLite数据库

import  sqlite3#sqlite基本的增删改查
conne=sqlite3.connect("test.bd")#创建链接数据库的对象  打开或创建数据库文件 没有打开就创建
print("成功打开")

c=conne.cursor()#获取游标

sql='''
 create table company
 (id int primary key not null,
 name int not null,
 salary real,
 address  char(50),
 age int not null);
'''

conne.execute(sql)
conne.commit()
conne.close()




print("成功建表")

出现了问题 哭泣
就是现实已经建立好了表,但是却找不到 呜呜呜
在这里插入图片描述
问题终于得到了解决,还是要归功于我不懈的努力,开心到模糊。我在搜呀搜呀的时候,上午搜了搜失败了,光弄了个DB browser,下午终于搜到了,原来是少了一步。不容易,终于能够继续了 开心
在这里插入图片描述

在这里插入图片描述

#3.插入数据
import  sqlite3#sqlite基本的增删改查
conne=sqlite3.connect("test.bd")#创建链接数据库的对象  打开或创建数据库文件 没有打开就创建
print("成功打开")

c=conne.cursor()#获取游标

sql1='''
 insert into company(id,name,salary,address,age)
 values (1,"张三",8000,32,42)
'''
sql2='''
 insert into company(id,name,salary,address,age)
 values (2,"李四",13000,30,40)
'''
conne.execute(sql1)#执行sql语句
conne.execute(sql2)#执行sql语句
conne.commit()#提交数据库操作
conne.close()#关闭数据库连接




print("成功插入数据")

在这里插入图片描述
查询数据

#4.查询数据
import  sqlite3#sqlite基本的增删改查
conne=sqlite3.connect("test.bd")#创建链接数据库的对象  打开或创建数据库文件 没有打开就创建
print("成功打开")

c=conne.cursor()#获取游标

sql="select id,name,salary,address,age from company"

#这里需要游标来接收数据
cursor=conne.execute(sql)#执行sql语句
for row in cursor:
    print("id= ",row[0])
    print("name= ",row[1])
    print("salary= ",row[2])
    print("address= ",row[3])
    print("age= ",row[4],"\n")
#查询不需要上交数据
conne.close()#关闭数据库连接




print("查询数据完毕")

在这里插入图片描述
新创建的movie250.db也建立成功。下午真顺
在这里插入图片描述
图标 关联文件改变
在这里插入图片描述
解决方法: PyCharm中如何修改文件默认打开方式(以自带数据库db.sqlite3为例)
本来该是问号,但是我不小心加上了文本,反而不好了。哎 SQLite这里的问题太多了,心累,我正在用SQLITE存储数据 但是遇到了问题,应该说该出现数据,但是没有 后续解决吧 昨天有个老师说 ,并不是要全部学会才能往后 ,我这太拘泥于小节了·。得往后啦 加油 后面再回来解决。

不好了 他让我在当前窗口中打开 妥淡了 前面都拜拜了 关键是SQLITE的那个程序我还没有粘上
真的完蛋了 emmmm 算了前面的难道都emmm

太好了没有完蛋 突然发现有一个打开最近 emmm 谢谢老师
赶紧把程序粘贴

# -* coding=utf-8 *-
#@Time=11:21 
#@Auhor=吴绍冲
#@Name=豆瓣.py
#@Software=PyCharm
#-*- codeing = utf-8 -*-
#@Time: 17:20
#@Author: 吴绍冲
#@File:t2.py
#@sofeware:PyCharm

#引入自定义模块
# from test1 import t1
#
#
# print(t1.add(3,5))
#引入系统模块
import sys
import os
import bs4
import re
import urllib.request
import urllib.error
from bs4 import BeautifulSoup
import csv

findlink = re.compile(r'<a href="(.*?)">')  # .代表一个字符,*代表0个或多个字符,?代表一次或多次。
# # 影片图片
findimgsrc = re.compile(r'<img.*src="(.*?)">', re.S)
"""
影片图片连接。re.S为包含换行符  常用于超链接这种复杂的东西堆砌,.不包含换行符。所以加上re.s后包含全部字符。
<img width="100" alt="肖申克的救赎" src="https://i-blog.csdnimg.cn/blog_migrate/1517f3c251488a6894c1d0bc4542aa02.webp?x-image-process=image/format,png" class="">
先看前面和后面 r'<img    ">',超链接用src="(.*?),中间杂碎 .*代表一个或多个字符,补充换行符。
"""
# # 影片名称
findtitle = re.compile(r'<span class="title">(.*)</span>')
# # <span class="title">肖申克的救赎</span>
# # 影片評分
findrating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#评论人数
findnum=re.compile(r'<span>(.*)</span>')#我竟然写的%d emmm数字是\d *代表多个
#一句话评论
findInq=re.compile(r'<span class="inq">(.*)</span>')#存疑
#详细介绍
findintro=re.compile(r'<p class="">(.*)</p>',re.S)





# <span class="rating_num" property="v:average">9.2</span>

def main():
    baseurl = "https://movie.douban.com/top250?start=0&filter="

    # 1.爬取网页
    datalist = getData(baseurl)
    # print('datalist:', datalist[0])
    # savepath = './/はじめまして.xls'
    dbpath="movie.db"


    askurl("https://movie.douban.com/top250?start=0&filter=")
    # 3.保存数据
    # saveData(datalist,savepath)#这里需要两个参数,把datalist保存到路径
    saveData2DB(datalist,dbpath)


"""
<a href="https://www.douban.com">模仿这个样子,所以里面是<a href="(.*?)">里面有了双引号,外面加单引号,
里面是单引号,外面是双引号。
"""


# 爬取网页
def getData(baseurl):
    datalist = []
    for i in range(0, 1):  # 调用获取信息的页面10次 一页25条 这个是左闭右开,实际是【0,10)。所以他会得到1-9
        url = baseurl + str(i * 25)
        html = askurl(url)  # 保存获取到的网页源码。接收。。

        """
        0代表第一个网页里的25条,9代表第十个网页。
        """
    file = open("./豆瓣.html", "rb")
    html = file.read().decode("utf-8")
    soup= BeautifulSoup(html, "html.parser")
    for item in soup.find_all("div", class_="item"):  # 不能直接写class,要加下划线
        # print(item)#测试,查看电影item全部信息
        data = []  # 保存一部电影的所有信息
        item = str(item)
        print(item)

        link = re.findall(findlink, item)[0]  # re库通过用正则表达式查找对应内容
        # print(link)
        # print(item)

        data.append(link)

        imgsrc = re.findall(findimgsrc, item)[0]
        data.append(imgsrc)

        titles = re.findall(findtitle, item)#片名可能只有一个中文名,没有外国名
        # 而且这个后面不能写【0[0]只代表第一个 因为我们一般爬取的有两个内容

        if len(titles)==2:
            ctitle=titles[0]
            data.append(ctitle)#可能有不存在的情况
            otitle=titles[1].replace("/","")
            data.append(otitle)#自己考虑的太不细致了 添加外国名
        else:
            data.append(titles[0])
            data.append(' ')#外文名留空
        print(data)

        #评分
        judgegrade=re.findall(findrating,item)[0]
        data.append(judgegrade)
        #评分人数
        judgenum=re.findall(findnum,item)[0]
        data.append(judgenum)
        #添加概述
        Inq=re.findall(findInq,item)
        if len(Inq)!=0:
            Inq=Inq[0].replace("。","")
            data.append(Inq)
        else:
            data.append("  ")

        #详细介绍


        bd=re.findall(findintro,item)
        bd=str(bd)
        bd=re.sub('<br(\s+)?/>(\s+)?',' ',bd)#去掉<br/>而且里面和外面可能存在一个或多个换行符,制表符
        # (\s)正则匹配 匹配任何空白字符,包括空格、制表符、换页符等等

        bd=re.sub("/","",bd)#一定记得在最后写对象

        data.append(bd.strip())#去掉头和尾巴的空格 换行
        print(data)

        datalist.append(data)#把处理好的一部电影信息放进datalist

    print(datalist)
    # 2.逐一解析数据
    return datalist


# 爬取一个url的信息
def askurl(url):
    headers = {
        "User-Agent": " Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}

    req = urllib.request.Request(url, headers=headers)

    try:
        response = urllib.request.urlopen(req)
        html = response.read().decode("utf-8")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html  # 返回网页代码

import xlwt
def saveData(datalist,savepath):

    workbook = xlwt.Workbook(encoding="utf-8",style_compression=0)  # 创建一个workbook对象encoding:设置编码,可写中文;style_compression:是否压缩,不常用

    worksheet = workbook.add_sheet('豆瓣top250',cell_overwrite_ok=True)  # 创建工作表  # cell_overwrite_ok:是否可以覆盖单元格,默认为False
    col=('链接','图片','中文名称','外文名称','评分','人数','一句话评价','详细介绍')#设置列名
    for i in range(0,8):
        worksheet.write(0,i,col[i])#列名
    for i in range(0,250):  #把内存写进去
        # print("第%d条" %(i+1))
        data=datalist[i]
        for j in range(0,8):
            worksheet.write(i+1,j,data[j])

    # worksheet.write(0,0,'hello')#第一个参数'行',第二个参数'列',第三个参数‘内容’
    workbook.save(savepath)#保存


#用SQLite存储
import  sqlite3
def saveData2DB(datalist,dbpath):#dbpath="movie.db"
    int_db(dbpath)#在保存之前先创建数据库
    conn=sqlite3.connect(dbpath)
    cur=conn.cursor()

    for data in datalist:
        for index in range(len(data)):
            data[index]='"'+data[index]+'"'
        sql='''
            insert into 豆瓣
            (       
           
            info_link,
            pic_link,
            cname,
            oname,
            score,
            rated,
            introduction,
            info
            )
            values(%s)'''%",".join(data)#前面的%是占位符,后面的代表在data之间加一个,
        print(sql)
        cur.execute(sql)
        conn.commit()
    cur.close()#关闭se()#关闭游标
    conn.close()#数据库链接


            
            
            

            
            
            
            
            











def int_db(dbpath):
        sql='''
        create table 豆瓣
        (
        id integer primary  key autoincrement,
        info_link text,
        pic_link text,
        cname varchar ,
        oname varchar ,
        score numeric ,    
        rated numeric ,
        introduction text,
        info text
          
            
        )
    
    
    
    
        '''#创建数据表---最关键的一步
        conn=sqlite3.connect(dbpath)#这个文件存在就是连接,不存在就是创建
        cursor=conn.cursor()#建立游标
        cursor.execute(sql)#执行sql语句
        conn.commit()#上交操作
        conn.close()#关闭数据库链接




if __name__ == '__main__':
    # main()
    int_db("pachong1.db")

    print("complete")

我改了不知道多少遍的结晶啊 emm 生活不易 多才多艺了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值