python里面有很多操作都类似于c语言,这里在爬取时主要需要注意用到的是for循环语句和各种库。
个人认为python中主要还是对库的运用比较占大比例。
(这里的软件版本是PyCharm 2020.3.2 x64)
所以,在爬取前先把这里所需要用到的库展示出来:
from bs4 import BeautifulSoup #网页解析,获取数据
import sys
import xlwt #进行excel操作
import re #正则表达式,进行文字匹配
import urllib #制定url,获取网页数据
import urllib.request
import urllib.error
import sqlite3 #进行SQLite数据库操作 <---最后一个
这里最后一个不在此次运用范围内,但是可以用其进行存储数据,本文选用的是用excel存储数据。
一. 整理架构
1,爬取网页
2,解析数据
3,保存数据
if _ _ name _ _ =="_ _ main _ _": 这个相当于int main()表示程序首先从这里进行,与此同时若是前面有顶格写的,则依旧是先从顶格写的开始写。
这里print()先执行,后面再执行if······语句里面的内容。
二.库的介绍
1. BeautSoup(bs4)
BeautifulSoup是将复杂HTML文档转换成一个复杂的树形结构,每个节点都是python对象,所有对象可以归纳为四种
–tag
–NavigableString
–BeautifulSoup
–Comment
原理:
from bs4 import BeautifulSoup
import re
file = open("./bs4使用.html","rb")#笔者已经事先在bs4使用.html文件夹里写入了指定网页的代码源
#file.write()
html = file.read().decode("utf-8")
bs = BeautifulSoup(html,"html.parser")#html.parser是解析器
print(bs.title)
print("****")
print(bs.title.string) #只打印里面的东西 即字符串
该代码显示:
提取指定内容:
print(bs.a)
print(bs.head)
print(type(bs.head)) #Tag 标签及其内容:只能拿到第一个
最终显示:
文档遍历,搜索,正则表达式搜索:
#文档遍历
print(bs.head.contents)
print(bs.head.contents[1])
#文档的搜索
#字符串过滤:会查找与字符串完全匹配的内容
t_list = bs.find_all("a") #标签必须为a,才输出
#正则表达式搜索:使用search()方法来匹配内容
t_list = bs.find_all(re.compile("a")) #只要包含a这个字母,就都输出
2.Urllib
制定URL,获取网页数据,访问url
内部原理:
(1).获得get请求(本文print用来查看该步骤是否进行或进行是否正确)
import urllib.request
#获取一个get请求
response = urllib.request.urlopen("http://www.baidu.com")#获取网页
print(response.read().decode('utf-8'))#decode('utf-8')解析代码,使中文也可以正常显示
其中这里urlopen,这个函数就是请求一个url的内容,这也是爬虫的第一步:网页请求,获取内容
(2).获取post请求
import urllib.parse#解析器
data = bytes(urllib.parse.urlencode({"hello":"world"}),encoding="utf-8") #转化成二进制,封装
response = urllib.request.urlopen("http://httpbin.org/post",data=data)
print(response.read().decode('utf-8'))
这里加了data参数就是以POST形式发送请求,否则就是GET方式了。
3.RE正则表达
用正则表达来获取想要的信息,提取数据。
这里用代码来展示:
import re
#No.1
pat=re.compile("AA")#AA是匹配对象,是正则表达式
flag=pat.search("454adaAAAAA") #此处是被校验的字符串
print(flag)
#No.2
m = re.search("ads","sdsjhiadsj")
print(m)
print(re.findall("a","dfuahhfuuafa"))
#校验所有的符合字符串,并形成列表['a','a','a']
print(re.findall("[a-z]","ahu54QFG5ds"))
#a到z符合的都可以
#如果是【a-z】 ['a', 'h', 'u', 'd', 's']
#如果是【a-z】+ ['ahu','ds']
print(re.sub("a","A","AFfsdfsAAaaff"))
#把字符串里的a用A替换
a=r"\aabd-\'"#这里r可以免去转义字符的符号
print(a)
#在正则表达式中,被比较的字符串在前面加r,不用担心转义字符的问题
4.xwlt存储数据
简单介绍
workbook = xlwt.Workbook(encoding="utf-8") #创建workbook对象
worksheet = workbook.add_sheet('sheet1') #创建工作表
worksheet.write(0,0,'hello') #写入数据,第一个是行,第二个表示列,第三个参数内容
workbook.save('student.xls')
这里举个例子,把99乘法表放入excel表格里:
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)))
workbook.save('99乘法表.xls')
可以在旁边的列表栏里找到建立的文档,打开后如下:
三.分步拆解
Ⅰ,主函数,囊括所有步骤
def main():
baseurl = "https://movie.douban.com/top250?start="
#1,爬取网页 & 2,解析数据
datalist = getdata(baseurl)
savepath = ".\\豆瓣电影Top250.xls"
#3,保存数据
savedata(datalist,savepath)
Ⅱ,爬取网页
def getdata(baseurl):
datalist = []
for i in range(0,10): #调用获取页面信息的网页·25页10次
url = baseurl + str(i*25)
html = askURL(url) #保存获取的网页源码
#2,逐一解析
soup = BeautifulSoup(html,"html.parser")
for item in soup.find_all('div',class_="item"): #查找符合要求字符串,形成列表
#print(item) #测试查看item的全部信息
data = [] #保持一部电影的所有信息
item = str(item) #把item变成字符串
#获取影片详情链接
link = re.findall(findlink,item)[0] #re用来查找指定字符串”正则表达式“
data.append(link) #添加链接
imgsrc=re.findall(findimgsrc,item)[0] #添加图片
data.append(imgsrc)
titles=re.findall(findtitile,item) #片名可能只有一个或中文名英文名都有
if(len(titles) == 2):
ctitle = titles[0]
data.append(ctitle)
etitile = titles[1].replace("/","") #去掉无关的符号
data.append(etitile)
else:
data.append(titles[0])
data.append(' ') #外国名留空
rating = re.findall(findrating,item)[0]
data.append(rating)
judge = re.findall(findjudge,item)[0]
data.append(judge)
inq = re.findall(findinq,item) #inq可能不存在
if len(inq) !=0:
inq = inq[0].replace("。","") #去掉句号
data.append(inq)
else:
data.append(" ")
bd = re.findall(findbd,item)[0]
bd = re.sub('<br(\s+)?/>(\s+)?'," ",bd) # 去掉<br/>
bd = re.sub('/'," ",bd) # 替换/
data.append(bd.strip()) # 去掉前后空格
datalist.append(data) #把处理好的一部电影信息放入datalist
# print(datalist)
return datalist
Ⅲ,获取网页全部数据&判断是否进入网页是否成功
def askURL(url): #列表
#head 模拟浏览器的头部信息,向豆瓣服务器发送消息
# 用户代理 表示告诉豆瓣服务器 我们是什么类型的机器·浏览器,防止被发现爬虫导致418
head = {
"User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Mobile Safari/537.36"
}
request = urllib.request.Request(url,headers=head) #携带头部信息header去访问url
html = ""
#try查看访问响应,有部分网页有防爬虫措施
try:
response = urllib.request.urlopen(request)
html = response.read().decode('utf-8')
#print(html)
except urllib.error.URLError as e:
if hasattr(e,"b"):
print(e.b)
if hasattr(e,"n"):
print(e.n)
return html
Ⅳ,保存数据
def savedata(datalist,savepath):
print("save....")
book = xlwt.Workbook(encoding="utf-8",style_compression=0) # 创建workbook对象
sheet = book.add_sheet('豆瓣电影Top250',cell_overwrite_ok=True) # 创建工作表
col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价人数","概况","相关信息")
for i in range(0,8):
sheet.write(0,i,col[i])
for i in range(0,250):
print("第%d条"%i)
data = datalist[i]
for j in range(0,8):
sheet.write(i+1,j,data[j])
book.save('豆瓣电影top250.xls')
Ⅴ,分类获取数据(re)
#影片详情链接规则
findlink = re.compile(r'<a href="(.*?)">') #创建正则表达式对象,表示规则(字符串模式) ()表示组
#影片图片的链接
findimgsrc = re.compile(r'<img.*src="(.*?)"',re.S)#.*?表示出现一连串字符0或1次 re.S忽略里面出现换行的情况
#影片片名
findtitile = re.compile(r'<span class="title">(.*)</span>')
#影片评分
findrating=re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
#评价人数
findjudge=re.compile(r'<span>(\d*)人评价</span>')
#概况
findinq=re.compile(r'<span class="inq">(.*)</span>')
#找到影片相关内容
findbd=re.compile(r'<p class="">(.*)</p>',re.S)
效果显示&待补充:
1,这里获取标题的地方有两个,因为部分作品既有中文名也有英文名;
2,在我们查看数据时发现有的作品有概述,有点没有,所以我们需要判断,因此插入了if语句。
最后的效果
若有不足,欢迎指出。