[B站视频]Python爬虫技术5天速成

  • 课程介绍
  • 1.Python基础概述
    • 课堂作业1:IF语句实现石头剪子布
    • 课堂作业2:用For和While循环打印九九乘法表
    • 字符串常见操作(只介绍部分常用到的)
    • 3.2列表
    • 课堂作业3
    • 3.3元组
    • 3.4字典
    • 3.5集合
    • 3.6总结:
  • 4.函数
  • 5.文件操作
    • 5.3文件的相关操作
      • 5.3.1文件重命名
      • 5.3.2删除文件
      • 5.3.3创建文件夹
      • 5.3.4获取当前目录
      • 5.3.5改变默认目录
      • 5.3.6获取目录列表
      • 5.3.7删除文件夹
  • 6.错误与异常
    • 课堂作业4
  • Python爬虫(任务驱动)
    • 1.任务介绍
    • 2.爬虫初识
    • 3.基本流程
      • 3.1准备工作
        • 3.1.1 分析页面
        • 3.1.2 编码规范
        • 3.1.3 引入模块
      • 3.2获取数据
        • 补充urllib
    • 补充BeautifulSoup
    • 补充:re模块
      • 3.3解析内容
      • 3.4保存数据
        • 3.4.1Excel表存储
    • 补充: SQLite
  • 最终爬虫代码
  • 数据可视化
    • 1.Flask入门
      • 1.1.1了解框架
      • 1.2.1从Helloworld开始
    • 动态-向网页传递一个变量(利用render_template(jinjia2)进行渲染):
    • 表单提交
    • 豆瓣数据可视化
      • 3.1首页制作
      • 3.2列表页制作
    • 2.Echarts应用
    • 3.WordCloud应用
  • 51job数据可视化项目
    • 1.项目说明
      • 1.1需求说明
      • 1.2 技术要求
    • 2.制作流程
      • 2.1 爬取数据
      • 2.2 数据保存
      • 2.3 搭建框架
      • 2.4 制作图表

课程介绍

B站课程链接
学习主题:Python爬虫和数据可视化
学习内容:
(1)Python语言的基础知识
(2)网络爬虫的技术实现
(3)数据可视化的技术应用(框架、组件等)
学习目标: 了解网络爬虫和数据可视化的技术原理与流程

1.Python基础概述

Python诞生和发展
1991年,第一个Python编译器(同时也是解释器)(可以解析你的指令了)诞生,它用C语言实现,并能调用C库。
2000年,Python2.0发布。
2008年,Python3发布。
基本介绍
Python是一门解释型(JAVA,C#不一样,需要先编译成一个中间状态,再运行中间状态文件,生成一个运行文件,而Python是写完之后直接可以执行的解释型语言)、面向对象(和JAVA一样,具有封装,继承,多态的功能)的高级编程语言。
Python是开源免费的、支持交互式、可跨平台移植的脚本语言。
Python的设计混合了传统语言的软件工程的特点和脚本语言的易用性,具有如下特性
1.开源、易于维护
2.可移植
3.易于使用、简单优雅
4.广泛的标准库、功能强大
5.可扩展、可嵌入
6. …
Python存在的缺点:
1.运行速度慢:Python是解释型语言,边执行需要边翻译成机器码,耗时,而C语言则在运行前直接编译成CPU能执行的机器码。但大量应用程序不需要那么快的运行速度,因为用户根本感觉不出来
2.代码不能加密:解释型语言发布程序就是发布源代码,而C语言只需要把编译后的机器码发布出去,从机器码反推出C代码是不可能的。
Python典型应用


1.3 第一个Python程序
在命令行/终端输入python或者python3进入python环境
退出python环境的方法:
1.用exit()
2.按Ctrl+Z(遇到死循环也可以用这种方法退出)

如何在命令行/终端直接执行python文件:
在命令行/终端直接输入

python <py文件名.py>

python3 <py文件名.py>

1.5 变量及类型
赋值(比如a=‘ABC’)时,Python解释器干了两件事:
1.在内存中创建一个‘ABC’的字符串
2.在内存中创建一个名为a的变量,并把它指向‘ABC’

1.6 标识符和关键字
什么是关键字
是python的一些具有特殊功能的标志符,这就是所谓的关键字,他们是python已经使用的,所以不允许开发者自己定义和关键字相同的名字的标志符
查看关键字代码:

import keyword
keyword.kwlist

返回结果是:

and  as  assert  break   class   continue    def del
elif    else    except  exec    finally for from    global
if  in  import  is  lambda  not or  pass
print   raise   return  try while   with    yield

1.7 输出
格式化输出:

age=18
print('这是我的年纪:%d岁'%age)

%d,格式化的是有符号十进制整数,%s也比较常用,格式化的是字符串

print('我的名字是%s,我的国籍是%s'%('小张','中国'))

补充:可以通过sep=’.'表示通过.将前面的字符串连接起来,如

print('www','baidu','com',sep='.')

返回结果是www.baidu.com
观察以下代码返回结果(功能已在代码注释中):

print('hello', end='')    # 打印之后不空格直接跟下一个内容
print('world', end='\t')  # 打印之后自动tab占位
print('python', end='\n') # 打印之后自动换行
print('end')            # 不对end参数赋值,则默认end='\n'

结果:

helloworld   python
python
end

1.8 输入

password = input('请输入密码:')
print('您刚刚输入的密码是:',password)
print(type(password)) # 即使输入的是数字,其实password存的还是字符串

注意: input输入得到的是字符串,所以后续进行print输出应该对应%s而不是%d
如果需要把字符串转换成整型,就需要使用强制类型转换int()

1.9 运算符和表达式
重点注意:假设a=10,b=21
:幂-返回x的y次幂,ab为10的21次方
//:取整除-返回向下取接近除数的整数,9//2的结果是4,-9//2的结果是-5

补充: 随机数模块

import random # 引入随机库
x = random.randint(0, 2) # 随机生成[0,2]的随机数,包含0、1、2
print(x)
### import与from...import
在python中用import或者from...import来导入相应的模块
将整个模块(somemodule)导入,格式为:import somemodule
从某个模块中导入某个函数,格式为:from somemodule import somefunction
从某个模块中导入多个函数,格式为:from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为:from somemodule import \*

课堂作业1:IF语句实现石头剪子布

import random
game_1 = input('请输入:剪刀(0)、石头(1)、布(2):') # 注意input里面的引号不要忘记
if game_1 not in ['0','1','2']: # 因为input赋予变量的类型是字符串,所以必须考虑not in['0','1','2']print('你输入的不是0,1,2中的任何一个')
else:if game_1 == 0:print('你输入为:剪刀(0)')elif game_1 == 1:print('你输入为:石头(1)')elif game_1 == 2:print('你输入为:布(2)')game_2 = random.randint(0,2)print('随机生成数字为:%d'%game_2)if (game_1==0 and game_2==2) or (game_1==1 and game_2==0) or (game_1==2 and game_2==1):print('啊,你赢了')elif game_1==game_2:print('哈哈,平局')else:print('哈哈,你输了:)')

补充: python可以用isinstance()函数来判断一个变量是否是某个类型,如

isinstance(a, int) # 判断变量a是否是int类型,是则返回TRUE,否则返回FALSE

课堂作业2:用For和While循环打印九九乘法表

for i in range(1,10):for j in range(1,i+1):print('%d*%d=%d'%(i,j,i*j),end='\t')print()

补充: r取消转义

print('hello\nchengdu') # 使用反斜杠,实现转义字符的功能
print(r'hello\nchengdu') # 在字符串前面加r,表示直接显示原始字符串,不进行转义

字符串常见操作(只介绍部分常用到的)

bytes.decode(encoding='utf-8',error='strict')

1.python3中没有decode方法,但我们可以使用bytes对象的decode()来解码给定的bytes对象,这个bytes对象可以由str.encode()来编码返回。

encode(encoding='utf-8',errors='strict')

2.以encoding指定的编码格式编码字符串,如果出错默认报一个ValueError的异常,除非errors指定的是‘ignore’或者‘replace’

str.isalnum()

3.如果字符串至少有一个字符并且所有字符都是字母或数字则返回True,否则返回False

str.isalpha()

4.如果字符串至少有一个字符并且所有字符都是字母,则返回True,否则返回False

str.isdigit()

5.如果字符串只包含数字,则返回True,否则返回False

str.isnumeric()

6.如果字符串只包含数字字符,则返回True,否则返回False(注意和isdigit()是有区别的,可以搜索相关博客来了解)

str.join(seq)

7.以指定字符串seq为分隔符,将str对象的所有的元素(的字符串表示)合并成一个新的字符串

len(str)

8.返回字符串长度

str.lstrip([chars])

9.截掉字符串左边的指定字符,chars为指定截取的字符,默认为空格

str.rstrip([chars])

10.删除 string 字符串末尾的指定字符,chars为指定截取的字符,默认为空格

str.split(str="", num=string.count(str))

11.以str为分隔符截取字符串,如果num有指定值,则仅截取num+1个字符串

3.2列表


补充:

list.index(obj,start,stop)

从list中的start开始到stop结束(不包括stop)去查找obj,查到则返回下标,查不到则报错

list.count(obj)

在list中统计obj对象有多少个,并返回

课堂作业3

products = [['iphone',6888],['MacPro',14800],['小米6',2499],['Coffee',31],['Book',60],['Nike',699]]
print('------ 商品列表 ------')
for i in range(len(products)):print('%d  %-5s\t%d'%(i,products[i][0],products[i][1])) # -5表示左对齐,且对应的字符串固定占用5个字符位store = []
while True:buy = input('请问您需要购买什么?请输入产品编号0-5(若完成购买则输入\'q\'退出):')if buy == 'q':breakelse:store.append(int(buy)) # 因为input得到的是字符串,所以需要int强制类型转换print('------ 购买的商品列表 ------')
total  = 0
store.sort() # 排序,为了让下面的列表好看一些
for index in store:value = products[index][1]print('%d  %-5s\t%d'%(index, products[index][0], value))total += valueprint('购买的商品总数为:',len(store))
print('购买的商品总价为:',total)

3.3元组

Tuple(元组)
元组的元素不可变,但可以包含可变对象,如list。
注意:定义一个只有1个元素的tuple,必须加逗号,如果不加逗号,则得到的并不是一个元组,而是本身小括号里面元素的类型。

3.4字典

字典的访问方式:

info = {'name': '吴彦祖','age':18}
print(info['name']) # 普通的直接访问
print(info['gender']) # 普通的直接访问,没找到会会报错
print(info.get('gender')) # 使用get方法,没有找到对应的键,默认返回None
print(info.get('gender','m')) # 可设置默认值,找到了则返回正确值,没找到则返回默认值

字典的删:

info = {'name': '吴彦祖','age':18}
print('删除前:%s'%info['name'])
del info['name'] # 删除整个键值对
print('删除后:%s'%info['name'])print('删除前:%s'%info)
del info # 删除整个字典变量
print('删除后:%s'%info)# [clear]
print('清空前:%s'%info)
info.clear() # 清空得到空的字典
print('清空后:%s'%info)

补充:通过枚举函数enumerate()为对象添加下标

mylist = ['a','b','c','d']
for i,x in enumerate(mylist): # enumerate让我们能同时获取下标和内容print(i,x)

3.5集合

3.6总结:

4.函数

补充:在函数内写global a是申明当前使用的是全局变量

5.文件操作

常用访问模式:
r:以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w:打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
rb:以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认格式。
wb:以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
文件读取的三种方式

# read方法,读取指定的字符,开始时定位在文件头部,每执行一次向后移动指定的字符数
f = open('test.txt','r')
content = f.read(5) # 读5个字符出来
print(content)
content = f.read(5)
print(content)
f.close()

read(n):读第n个字符
readlines():把整个文档都读入了一个list中,每行对应list的一个元素
readline():一次读一行

5.3文件的相关操作

有时候需要对文件进行重命名、删除等曹走,python中的os有这些功能

5.3.1文件重命名

import os
os.rename(需要修改的文件名, 新的文件名)

5.3.2删除文件

import os
os.remove(待删除的文件)

5.3.3创建文件夹

import os
os.mkdir(文件夹名)

5.3.4获取当前目录

import os
os.getcwd()

5.3.5改变默认目录

import os
os.chdir('../')

5.3.6获取目录列表

import os
os.listdir('./')

5.3.7删除文件夹

import os
os.rmdir(文件夹名)

6.错误与异常

捕获异常:

# 捕获异常
try:print('--------test------1---')f = open('123.txt','r')print('--------test------2---')
except IOError: # 文件没找到属于IO异常-IOError(输入输出异常)pass        # 捕获异常后,执行的代码

异常类型想要被捕获,必须要一致

try:print(num)
except NameError:  # 异常类型想要被捕获,必须要一致print('产生错误了')

将可能产生的所有异常类型,都放到括号中

try:print('--------test------1---')f = open('test1.txt','r')print('--------test------2---')print(num)
except (NameError, IOError):  # 将可能产生的所有异常类型,都放到括号中print('产生错误了')

获取错误描述(except Error类型 as result)

try:print('--------test------1---')f = open('123.txt','r')print('--------test------2---')print(num)
except (NameError, IOError) as result:  print('产生错误了')print(result)

捕获所有异常(except Exception)

try:print('--------test------1---')f = open('123.txt','r')print('--------test------2---')print(num)
except Exception as result: # Exception可以承接任何异常print('产生错误了')print(result)

try…finally 和嵌套

import time
try:f = open('test1.txt','r') # 文件打开try :while True:content = f.readline()if len(content) == 0:breaktime.sleep(2)print(content)finally:            # 如果能进入第二层try,说明文件打开了,文件打开。第二层try无论报任何错,都需要colse文件f.close()print('文件关闭')except Exception as result:print('发生异常')print(result)

课堂作业4

# 通过python新建一个gushi.txt,选择一首古诗写入文件中
def write_file(file_name,gushi):f = open(file_name,'w') # 在这里我默认写文件不会出错try:f.writelines(gushi)except Exception as result:print('文件写入出错了,原因是:',result)finally:f.close()write_file('gushi.txt',['床前明月光\n','疑是地上霜\n','举头望明月\n','低头思故乡'])# 另外写一个函数,读取指定文件gushi.txt,将内容复制到copy.txt中,并在控制台输出'复制完毕'。
def read_file(file_name):try:f = open(file_name,'r')try:content = f.readlines()finally:f.close()return contentexcept Exception as result:print('读取文件错误,原因是:',result)content = read_file('gushi.txt')
write_file('copy.txt', content)
print('复制完毕')

Python爬虫(任务驱动)

1.任务介绍

需求分析
爬取豆瓣电影Top250的基本信息,包括电影的名称、豆瓣评分、评价数、电影概况、电影链接等。要爬取的网站

2.爬虫初识

什么是爬虫:网络爬虫,是一种按照一定规则自动抓取互联网信息的程序或者脚本。由于互联网数据的多样性和资源的有限性,根据用户需求定向抓取相关网页并分析已成为如今主流的爬取策略。
爬虫的本质是什么模拟浏览器打开网页,获取网页中我们想要的那部分数据。

3.基本流程

准备工作:通过浏览器查看分析目标网页,学习编程基础规范。
获取数据:通过HTTP库向目标站点发起请求,请求可以包含额外的header等信息,如果服务器能正常响应,会得到一个Response,便是所要获取的页面内容。
解析内容:得到的内容可能是HTML、json等格式,可以用页面解析库正则表达式等进行解析。
保存数据:保存形式多样,可以存为文本,也可以保存到数据库,或者保存特定格式的文件。

3.1准备工作

URL分析:
第一页对应的URL为:https://movie.douban.com/top250
第二页对应的URL为:https://movie.douban.com/top250?start=25&filter=
其中的&filter=没有取值,所以可以去掉并不会影响,有用的主要是start=25,他表示显示下标从25开始的电影(下标从0开始,所以实际上对应的标签是26)

总结:
页面包括250条电影数据,分10页,每页25条
每页的URL的不同之处:最后的数值=(页数-1)*25

3.1.1 分析页面

借助浏览器开发者工具来分析网页,在Elements下找到需要的数据位置

3.1.2 编码规范

一般Python程序第一行需要加入# -*- coding: utf-8 -*- 或者 # coding=utf-8,这样可以在代码中包含中文
Pytho文件中可以加入main函数用于测试程序:if __name__ == '__main__':

3.1.3 引入模块

模块(module):用来从逻辑上组织python代码(变量、函数、类),本质就是py文件,提高代码的可维护性。Python使用import来导入模块,如import sys
模块module一般情况下是以.py来后缀的文件。

3.2获取数据

补充urllib

get请求:

import urllib.request#获取一个get请求
response = urllib.request.urlopen('http://www.baidu.com') # 等同于request.get(),后者更简单
print(response.read().decode('utf-8'))  # 一行显示的话需要打开soft-wrap,参考:https://blog.csdn.net/qq_38157825/article/details/89331743

当用urllib去获取一个网页的时候,建议对返回来的内容进行一个解码
补充:一个提供http请求和响应服务的测试网站:http://httpbin.org/
post请求:

#获取一个post请求
import urllib.parse
data  = bytes(urllib.parse.urlencode({'hello':'world'}),encoding='utf-8')
response = urllib.request.urlopen('http://httpbin.org/post',data)
print(response.read().decode('utf-8'))

超时处理:

# 超时处理,try_except
try:response = urllib.request.urlopen('http://httpbin.org/get',timeout=0.01)print(response.read().decode('utf-8'))
except urllib.error.URLError as e:print('time out!')

获取头部信息:

response = urllib.request.urlopen('http://www.baidu.com')
# print(response.status) # response包含状态码
print(response.getheaders()) # response包含头部信息
print(response.getheader('Server')) # 拿具体一个属性就是getheader

如果被发现是爬虫,可能会返回418Error(有一个梗-我是茶壶),所以需要伪装成浏览器
模拟浏览器:

url  = 'http://httpbin.org/post'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 QQBrowser/4.4.119.400'
}  # 键值对可以增加更多
data = bytes(urllib.parse.urlencode({'name':'eric'}), encoding='utf-8')
req = urllib.request.Request(url=url, data=data, headers=headers,method='POST') # 构建请求对象
response = urllib.request.urlopen(req) # 发起请求,返回响应
print(response.read().decode('utf-8'))

访问豆瓣:

url = 'https://www.douban.com'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 QQBrowser/4.4.119.400'
} # 伪装浏览器
req = urllib.request.Request(url = url,headers=headers)
response = urllib.request.urlopen(req)
print(response.read().decode('utf-8'))

补充:有时User-Agent只指定为Mozilla/5.0就可以伪装成功了
补充contrl+shift+J可以快速合并到一行

补充BeautifulSoup

补充资料:
beautifulsoup4简介
Beautiful Soup 4.2.0 文档

BeautifulSoup4将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种:

  • Tag
  • NavigableString
  • BeautifulSoup
  • Comment
from bs4 import BeautifulSoupfile = open('./baidu.html','rb')
html = file.read()
bs = BeautifulSoup(html,'html.parser')#1.Tag: 标签
print(bs.title) # 返回:<title>百度一下,你就知道 </title>
# print(bs.a)
# print(bs.head)
print(type(bs.head)) # 类型为bs4.element.Tag#2.NavigableString: 标签里的内容(字符串)
print(bs.title.string) # 返回:百度一下,你就知道
print(type(bs.title.string)) # 类型为bs4.element.NavigableString
print(bs.a.attrs) # 拿到一个标签里面的所有属性#3.BeautifulSoup:  表示整个文档
print(type(bs))
print(bs.name)
print(bs.attrs)
print(bs)#4.comment: 是一个特殊的NavigableString,但输出的内容不包含注释符号
print(bs.a.string)
print(type(bs.a.string))

文档的遍历:

# 文档的遍历
print(bs.head.contents) # 返回一个list
print(bs.head.contents[1])
# 更多内容,搜索网络相关

文档的搜索:

# (1)find_all()--最常用
# 字符串过滤:会查找与字符串完全匹配的内容
t_list = bs.find_all('a') # 查询所有的a标签
# print(t_list)import re
# 正则表达式:使用search()方法来匹配内容
t_list = bs.find_all(re.compile('a')) # 查询其中带有字符a的所有标签
# print(t_list)# 方法:传入一个函数(方法),根据函数的要求来搜索(了解)
def name_is_exists(tag): #搜索并返回标签里面含有name属性的return tag.has_attr('name')t_list = bs.find_all(name_is_exists)
# print(t_list)# 2.kwargs      参数
t_list = bs.find_all(id='head')
t_list = bs.find_all(class_=True) # class是python的保留字,所以bs4作者加了下划线(规定)
t_list = bs.find_all(href='http://news.baidu.com') # 精确查找
# for item in t_list:# print(item)# 3.text参数
t_list = bs.find_all(text='hao123')
t_list = bs.find_all(text=['hao123','地图','贴吧','我'])
t_list = bs.find_all(text=re.compile('\d')) # 应用正则表达式来查找包含特定文本的内容(标签里的字符串)
# for item in t_list:# print(item)# 4.limit参数
t_list  = bs.find_all('a',limit=3) # 限制获取的个数
# for item in t_list:# print(item)# 5.css选择器
t_list = bs.select('title') # 通过标签来查找
t_list = bs.select('.mnav') # 通过类名来查找,.表示查找的是类,跟的mnav是类名
t_list = bs.select('#u1')   # 通过id来查找,#表示查找的是id,跟的u1是id名
t_list = bs.select("a[class='bri']") # 通过属性来查找
t_list = bs.select('head>title') # 通过子标签来查找
# for item in t_list:
#     print(item)t_list = bs.select('.mnav ~ .bri') # 跟.mnav是兄弟的一个标签,且该兄弟标签值是.bri
print(t_list[0].get_text())

补充:re模块

正则表达式的常用操作符号(1)

补充:史上最全正则表达式大全链接
补充: Re库主要功能函数

正则表达式的匹配模式控制

3.3解析内容

解析页面内容:
1.使用BeautifulSoup定位特定的标签位置
2.使用正则表达式找到具体的内容

对爬取的html进行解析
1.使用BeautifulSoup定位特定的标签位置(类名为’item’的div标签):

soup = BeautifulSoup(html, 'html.parser')    #使用html.parser解析器
for item in soup.find_all('div', class_="item"): # 查找符合要求的字符串,形成列表

注意: class是python关键字,所以必须写class_

2.使用正则表达式找到具体的内容:(以解析’影片详情链接’举例)
定义查找’影片详情’的正则表达式:

# 影片详情链接的规则
findLink = re.compile(r'<a href="(.*?)">')

利用re库来通过正则表达式查找指定的字符串:

link = re.findall(findLink, item)[0]     #re库用来通过正则表达式查找指定的字符串

补充:python 爬虫爬取内容时, \xa0 、 \u3000 的含义与处理方法

str = str.replace(u'\xa0', u'') #去掉'\xa0'

3.4保存数据

3.4.1Excel表存储

利用python库xlwt将抽取的数据datalist写入Excel表格

# 保存数据
import xlwt # 进行excel操作
def saveData(datalist, savepath):print('save....')book = xlwt.Workbook(encoding='utf-8') # 创建工作簿sheet = book.add_sheet('豆瓣电影Top250')# 添加工作表col = ('电影详情链接','图片链接','影片中文名','影片外文名','评分','评价数','概况','相关信息')                            # 列名设置for i in range(0,8):sheet.write(0,i,col[i])           # 写入列名for i in range(0,250):print("第%d条"%(i+1))data = datalist[i]for j in range(0,8):sheet.write(i+1,j,data[j])    # 往工作表单元格写入数据book.save(savepath)                   # 保存表格

补充: SQLite

连接数据库:

import sqlite3
# 1.连接数据库
conn = sqlite3.connect('test.db')  # 打开或创建数据库文件
print('成功打开数据库')

创建数据表:

# 2.创建数据表
conn = sqlite3.connect('test.db')  # 打开或创建数据库文件
print('成功打开数据库')
c = conn.cursor() # 获取游标sql = '''create table company(id int primary key not null,name text not null,age int not null,address char(50),salary real);
'''c.execute(sql)    # 执行sql语句
conn.commit()        # 提交数据库操作
conn.close()      # 关闭数据库连接
print('成功建表')

插入数据:

conn = sqlite3.connect('test.db')  # 打开或创建数据库文件
print('成功打开数据库')
c = conn.cursor() # 获取游标sql1 = '''insert into company (id, name, age, address, salary)values (1,'张三',32,'成都',8000);
'''
sql2 = '''insert into company (id, name, age, address, salary)values (2,'李四',30,'重庆',15000);
'''c.execute(sql1)    # 执行sql语句
c.execute(sql2)    # 执行sql语句
conn.commit()        # 提交数据库操作
conn.close()      # 关闭数据库连接
print('插入数据完毕')

查询数据:

conn = sqlite3.connect('test.db')  # 打开或创建数据库文件
print('成功打开数据库')
c = conn.cursor() # 获取游标sql = '''select id, name, address, salary from company'''cusor = c.execute(sql)    # 执行sql语句for row in cusor:print('id = ', row[0])print('name = ', row[1])print('address = ', row[2])print('salary = ', row[3],'\n')# conn.commit()           # 查询不需要提交
conn.close()      # 关闭数据库连接
print('查询完毕')

最终爬虫代码

#-*- coding = utf-8 -*-
#@Time ; 15/06/2020 10:48
#@Author : 张亿锋
#@File : spider.py
#@Software : PyCharmfrom bs4 import BeautifulSoup  # 网页解析,获取数据
import re   # 正则表达式,进行文字匹配
import urllib.request, urllib.error # 制定URL,获取网页数据
import xlwt # 进行excel操作
import sqlite3 # 进行SQLite数据库操作def main():baseurl = 'https://movie.douban.com/top250?start='#1.爬取网页datalist = getData(baseurl)#2.保存数据到excel表格中# savepath = '豆瓣电影Top250.xls'# saveData(datalist,savepath)#2.保存数据到数据库中dbpath = 'movie.db'saveData2DB(datalist, dbpath)#影片详情链接的规则
findLink = re.compile(r'<a href="(.*?)">')     #创建正则表达式对象,表示规则(字符串的模式),这里?是最小匹配,即非贪婪匹配,#括号表示一个组,等会findall返回的就是这个组的匹配上的字符串的这个组的内容
# findmagSrc = re.compile(r'<img.*src="(.*?)".*>')
#影片图片的链接
findmagSrc = re.compile(r'<img.*src="(.*?)"',re.S) #re.S模式:使.匹配包括换行在内的所有字符
#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
#影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#找到评价人数
findJudge = re.compile('<span>(\d*)人评价</span>')
#找到概况
findInq = re.compile(r'<span class="inq">(.*)</span>')
#找到影片的相关内容
findBd = re.compile(r'<p class="">(.*?)</p>',re.S) # 必须要有?, 否则匹配会去匹配直到第二个</p># 爬取网页
def getData(baseurl):datalist = []for i in range(0,10): # 调用获取页面信息的函数10次url = baseurl + str(i*25)html = askURL(url) # 保存获取到的网页源码# 2.逐一解析数据soup = BeautifulSoup(html, 'html.parser')    #使用html.parser解析器for item in soup.find_all('div', class_="item"): # 查找符合要求的字符串,形成列表# print(item)   # 测试: 查看电影item全部信息data = []       # 保存一部电影的所有信息item = str(item)#影片详情的链接link = re.findall(findLink, item)[0]     #re库用来通过正则表达式查找指定的字符串data.append(link)                        #添加链接imgSrc = re.findall(findmagSrc, item)[0]data.append(imgSrc)                      #添加图片titles = re.findall(findTitle, item)     #片名可能只有一个中文名,没有外文名if (len(titles) == 2):ctitle = titles[0]data.append(ctitle)                  #添加中文名otitle = titles[1].replace('/','')   #去掉无关的符号otitle = otitle.replace(u'\xa0', u'')  # 去掉无关的符号data.append(otitle)                  #添加外文名else:data.append(titles[0])data.append(' ')                     #留空rating = re.findall(findRating,item)[0]data.append(rating)                      #添加评分judgeNum = re.findall(findJudge,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(findBd, item)[0]# \s是指空白,包括空bai格、换行、tab缩进等所有的空白,单独的问号表示匹配前面的子表达式0次或者1次bd = re.sub('<br(\s+)?/>(\s+)?',' ',bd)  #去掉<br/>bd = re.sub('/',' ',bd)                  #替换/bd = bd.replace(u'\xa0', u'')data.append(bd.strip())                  #去掉前后的空格datalist.append(data)                    #把处理好的一部电影信息放入datalist# print(datalist) # 测试return datalist# 得到指定一个URL的网页内容
def askURL(url):head = {} # 模拟浏览器头部信息,向豆瓣服务器发送消息# 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器,浏览器(本质上是告诉刘篮球,我们可以接受什么水平的文件内容)head['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 QQBrowser/4.4.119.400' # contrl+shift+J可以快速合并到一行request = urllib.request.Request(url,headers=head)html = ''try:response = urllib.request.urlopen(request)html = response.read().decode('utf-8')# print(html)except urllib.error.URLError as e:if hasattr(e,'code'):print(e.code) # e.code是错误代码if hasattr(e,'reason'):print(e.reason) # e.reason是错误原因return html# 保存数据
def saveData(datalist, savepath):print('save....')book = xlwt.Workbook(encoding='utf-8')sheet = book.add_sheet('豆瓣电影Top250')col = ('电影详情链接','图片链接','影片中文名','影片外文名','评分','评价数','概况','相关信息')for i in range(0,8):sheet.write(0,i,col[i]) # 列名for i in range(0,250):print("第%d条"%(i+1))data = datalist[i]for j in range(0,8):sheet.write(i+1,j,data[j])book.save(savepath)def saveData2DB(datalist, dbpath):init_db(dbpath)conn = sqlite3.connect(dbpath)cur = conn.cursor()for data in datalist:for index in range(len(data)):if index == 4 or index == 5:continuedata[index] = '"'+str(data[index])+'"' # score和rated不需要sql = '''insert into movie250 (info_link, pic_link, cname, ename, score, rated, introduction, info) values (%s)'''%",".join(data)print(sql)cur.execute(sql)conn.commit()cur.close()conn.close()def init_db(dbpath):sql  = '''create table movie250(id integer primary key autoincrement,info_link text,pic_link text,cname varchar,ename varchar,score numeric,rated numeric,introduction text,info text)    '''     # 创建数据表conn = sqlite3.connect(dbpath)cursor = conn.cursor()cursor.execute(sql)conn.commit()conn.close()if __name__ == '__main__':main()# init_db('movietest.db') # 测试print('爬取完毕')

数据可视化

1.Flask入门

1.1.1了解框架

Flask作为Web框架,它的作用主要是为了开发Web应用程序。那么我们首先来了解下Web应用程序。Web应用程序(World Wide Web)诞生最初的目的,是为了利用互联网交流工作文档。

1.2.1从Helloworld开始

框架:

from flask import Flask, render_template,request
app = Flask(__name__) # 初始化
# 路由解析,通过用户访问的路径,匹配相应的函数
@app.route('/')
def hello_world():return 'Hello World!'
if __name__ == '__main__':app.run()

补充: debug模式务必开启,开启方法是:右上角

点击Edit Configurations后,勾选FLASK_DEBUG
通过访问路径,获取用户的字符串参数:

# 通过访问路径,获取用户的字符串参数
@app.route('/index/<name>')
def welcome(name):return '你好,%s'%name

通过访问路径,获取用户的整型参数:

# 通过访问路径,获取用户的整型参数
@app.route('/index/<int:id>')
def welcome2(id):return '你好,%d号的会员'%id

补充: 此外,还可设置float类型。总之,通过填写不同的参数(不同的访问路径),可以进入不同的路径,到不同的网页。
注意: 路由路径不能重复,用户只能通过唯一路径来访问特定的函数。(当然可以通过不同的函数进入之后再跳转到其他函数,但这里不做介绍)
返回利用render_template(jinjia2)渲染网页:

# 返回给用户渲染后的网页文件
@app.route('/i')
def index2():return render_template('index.html')

动态-向网页传递一个变量(利用render_template(jinjia2)进行渲染):

三种变量类型:
普通变量
列表类型变量
字典类型变量

1.传递普通变量:

@app.route('/i3')
def index3():time = datetime.date.today()    # 普通变量return render_template('index.html',var = time)

在网页html中使用var变量的方式:

今天是{{ var }}, 欢迎光临.

2.传递列表类型变量:

@app.route('/i3')
def index3():time = datetime.date.today()    # 普通变量name = ['小张','小王','小赵']     # 列表类型return render_template('index.html',var = time, list = name)

在网页html中使用list变量的方式:

{% for data in list %}   <!--用大括号和百分号括起来的是控制结构,还有if,可自行了解--><li> {{ data }} </li>
{% endfor %}

3.传递字典类型变量:

@app.route('/i3')
def index3():time = datetime.date.today()    # 普通变量name = ['小张','小王','小赵']     # 列表类型task = {'任务':'打扫卫生','时间':'3小时'} # 字典类型return render_template('index.html',var = time, list = name, task = task)

注意: 实际中常采用类似task=task的写法,前面的表示传入html的参数名,后面是在.py文件中的变量名
在网页html中使用task变量的方式:(这里结合了表格)

<table border="1">{% for key,value in task.items() %} <tr><td>{{ key }}</td><td>{{ value }}</td></tr>{% endfor %}
</table>

表单提交

1.构建表单提交的页面register.html:

{#<form action="http://localhost:5000/result" method="post">#}
<form action="{{ url_for('result')}}" method="post"> <!--不使用localhost,而是通过反向路由(根据路由函数名得到路由地址)--><p>姓名: <input type="text" name="姓名"></p><p>年龄: <input type="text" name="年龄"></p><p>性别: <input type="text" name="性别"></p><p>地址: <input type="text" name="地址"></p><p><input type="submit" value="提交"></p>
</form>

注意: 不使用localhost,而是通过反向路由(根据路由函数名得到路由地址)
2.在app.py中添加register.html的访问路径和访问路由:

# 表单提交
@app.route('/test/register')
def register():return render_template('test/register.html')

3.构建接受表单提交显示的页面result.html:

<table border="1">{% for key,value in result.items() %}<tr><th>{{ key }}</th><td>{{ value }}</td></tr>{% endfor %}
</table>

4,构建接受表单的访问路径和访问路由:

from flask import request
@app.route('/result', methods = ['POST','GET'])
def result():if request.method == 'POST':result = request.form # request可以获取所有提交的表单信息,生成字典return render_template('test/result.html',result = result)

注意: 接受表单提交的路由,需要指定methodsPOST

豆瓣数据可视化

3.1首页制作

3.2列表页制作

2.Echarts应用

补充: GitHub上的js和css一般是不能单独下载的。如需下载需要下载整个文件,比如下载.zip后缀的包,然后解压,取出自己想要的js或css文件。
注意: 字符串经过jinjia渲染后可能会出现转义字符的问题

for item in data:score.append(str(item[0])) # score是字符串列表num.append(item[1])
cur.close()
conn.close()
return render_template('score.html', score=score, num=num)

html中按通常方式调用score

data: {{ score }}

html源码中出现转义字符显示问题:

data: [&#39;8.3', '8.4', '8.5', '8.6', '8.7', '8.8', '8.9', '9', '9.1', '9.2', '9.3', '9.4', '9.5', '9.6', '9.7']

修改的方法:在html中用下面代码调用score(把内容转化成json格式的)

data: {{ score|tojson }}

3.WordCloud应用

注意:pycharmsettings-project interpreter中找不到jieba模块的话,可以考虑点击

51job数据可视化项目

1.项目说明

1.1需求说明

项目名称: 51job招聘网数据爬取分析平台
项目背景: 随着互联网在中国的普及,网络招聘景气不断攀升。它允许以更加灵活的交互方式,提供更加丰富 的信息资源。为求职者提供更加多样、精确、新鲜的招聘信息。

项目意义: 面对眼花缭乱的招聘信息,帮助求职者能够通过招聘信息的数据可视化,分析招聘薪资等信息的分 布,明确自己的方向,找到适合的工作。

项目目标:
1、实现通过搜索对相关招聘的主要信息进行展示、下载(选做)。
2、对搜索出的信息进行地域、薪资、工作经验、学历、职责与要求等个方面的数据可视化分析。

1.2 技术要求

技术环境: Python3、urllib库、flask框架、Echarts.js、wordcloud库、sqlite3数据库

分工要求: 每组4-5人,每人有一个菜单项,完成相应的数据可视化的功能展示,功能不能相同。
菜单项包括:首页、列表页(分页选做)、Echarts图表2-3个、词云0-1个、团队介绍页(选做)

考核内容:
+ 基本功能:
1.使用爬虫爬取51job数据至少1000条,并保存到数据库中
2.应用flask框架完成网站搭建并能够本地访问
3.能够引导用户搜索关键词,完成相应内容可视化的展现

+ 鼓励创新:
1.数据呈现的多样化:多种图表形式
2.数据维度的设计:能够从不同维度的数据分析,为用户提供更多价值
3.界面表现的美化

提交材料:
项目源码
实验报告

2.制作流程

2.1 爬取数据

爬取列表

  • 51job字符集为gbk
    所以编码解析需要设置为gbk
  • url二次解析
    在51job上搜索中文(如大数据),在url显示的其实是二次编码后的结果,为此我们需要模拟二次编码,代码如下
from urllib import parse
keyword = parse.quote('大数据')
newKW = parse.quote(keyword)  # 二次编码
  • 使用选择器实现文字提取
    如果不想使用正则表达式从html中提取数据,则可以通过选择器提取数据,具体的,
    先通过F12定位到需要html中需要提取的区域,然后根据标签递进顺序进行选择,代码如下:
html = open('jobList.heml', 'r')
bs = BeautifulSoup(html, 'html.parser')
eldiv = bs.select('.el > .t1 > span > a')
for link in eldiv:print(link.text.strip())

爬取详情

  • 字符串截取:str.[n:m] 截取从下标n到m个字符
  • 分隔:str.split('|') 按照|分隔字符串为列表
  • 去除特殊符号:str.replace('/r','') 替换'/r'为空白字符串
  • 去除前后空格:str.strip()

2.2 数据保存

建议采用成熟的模版
前端页面
模版推荐:
https://bootstrapmade.com/ 国外网站,需要翻墙才能访问
https://colorlib.com/wp/templates/ 国内可访问
https://colorlib.com/wp/free-bootstrap-admin-dashboard-templates/ 加载较慢

视频里面的模版:
https://startbootstrap.com/themes/sb-admin-2/

列表显示
表单制作:

  • 表单传值

2.3 搭建框架

2.4 制作图表

[B站视频]Python爬虫技术5天速成相关推荐

  1. python快速注释html5_P29-30《Python爬虫技术5天速成…》学习过程笔记16(超详细记录)...

    对应原视频 第29集  补充flask(上) & 第30集  补充flask(下): 本篇概要: P29 --flask框架的样子 --创建flask框架后直接运行就报错.测试.解决 --通过 ...

  2. python如何设计爬虫界面软件_Python+PyQt5设计B站视频数据爬虫小程序

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. 以下文章来源于菜J学Python ,作者J哥 前言 目前,市场上有大量 Python图形用户界面( ...

  3. python爬网页数据用什么_初学者如何用“python爬虫”技术抓取网页数据?

    原标题:初学者如何用"python爬虫"技术抓取网页数据? 在当今社会,互联网上充斥着许多有用的数据.我们只需要耐心观察并添加一些技术手段即可获得大量有价值的数据.而这里的&quo ...

  4. 基于python爬虫技术的应用_基于Python爬虫技术的应用

    办公自动化杂志 一.引言 本文主要是对 Python 爬虫技术进行阐述,基于 python 的爬虫与其他语言相比的有很多优势.通过爬去某个网站的所有新闻这个案例,来进一步阐释 Python 爬虫技术的 ...

  5. python爬虫技术如何挣钱?教你爬虫月入三万

    爬虫技术挣钱方法1:接外包爬虫项目 这是网络爬虫最通常的的挣钱方式,通过外包网站,熟人关系接一个个中小规模的爬虫项目,一般向甲方提供数据抓取,数据结构化,数据清洗等服务. python爬虫技术如何挣钱 ...

  6. 用Python爬虫技术怎么挣点小钱,这四种方法可行

    提醒:抓取的数据如果要商业化,要小心知识产权问题噢.还要提醒一点:抓取和处理这些数据的代价要小于人工处理的代价,使用爬虫代替人工才有价值. 我利用Python爬虫技术赚点小钱方式,在正式聊Python ...

  7. python爬虫怎么赚钱-个人利用Python爬虫技术怎么挣钱-10万被动收入...

    我利用Python爬虫技术年挣10万被动收入的方式,在正式聊Python爬虫技术之前,先来说说挣钱的事,说说作为一个自由职业或兼职者怎么利用爬虫来挣钱. 个人爬虫挣钱方法大致如下 爬虫技术挣钱方法1: ...

  8. Python+爬虫技术获取斗鱼直播图片(整理)

    核心内容: 1.爬虫的基本原理 2.利用Python爬取数据的方法(使用urllib爬取数据) 3.从斗鱼直播平台爬取图片 最近因为工作的原因,要利用爬虫的相关技术,获取html网页相关的数据,特意总 ...

  9. 如何用python抓取文献_浅谈Python爬虫技术的网页数据抓取与分析

    浅谈 Python 爬虫技术的网页数据抓取与分析 吴永聪 [期刊名称] <计算机时代> [年 ( 卷 ), 期] 2019(000)008 [摘要] 近年来 , 随着互联网的发展 , 如何 ...

最新文章

  1. 清华大学计算机博士,带你搞定大厂面试题
  2. 计算机网络总结:第一章 计算机网络和因特网
  3. 工程搭建:搭建子工程之分布式id生成器
  4. python声明数组_在Python中如何声明动态数组
  5. fillrect不填充被覆盖的区域 mfc_quot;条带覆盖quot;猜想的中二证明:quot;球面条线覆盖或点覆盖quot;积分π...
  6. 数据结构 实践项目——数据结构、算法、程序设计
  7. 将一张100元按如下要求C语言,aoa三一宝典(计算机二级考试)
  8. linux抓取僵尸网络进程脚本
  9. Anaconda spyder下载第三方包
  10. 美团2018校园招聘 研发工程师(三)
  11. Android 设置gif动态桌面
  12. 315晚会实在涨知识
  13. 基尔霍夫(kirchhoff)矩阵树定理
  14. 泉州php编程学校,泉州五中校园网络平台【Moodle平台与校园网络整合】...
  15. 27岁转行软件测试,成功虽晚但不迟,写给跟我一样迷茫的人。
  16. cassandra读写数据
  17. CD刻录之Nero Burning ROM
  18. 初到深圳面试分享(下)
  19. IIS上安装Web平台安装程序
  20. (一)云计算技术学习--基础概念

热门文章

  1. 那些年啊 那些事——一个程序员的奋斗史 ——89
  2. linux 添加开机动画,如何更改linux 开机画面?
  3. 解决Ubuntu16.04卡在开机画面
  4. Linux中怎么搭建Discuz论坛
  5. 三菱触摸屏u盘上传和下载_Smart700 IE V3触摸屏怎样用U盘下载程序-工业支持中心-西门子中国...
  6. Linux 一句精彩的回答【转】
  7. 微信交易单号和订单号的区别
  8. C---------------LessonCircle
  9. 程序设计与算法 | (3) 输入输出与运算符、表达式
  10. 系统注册表方式修改背景颜色