爬虫的本质
模拟浏览器打开网页,获取网页中我们想要的数据
搜索就是将站点爬取再展示
一、准备工作
-
前提知识
a) python基础
菜鸟教程,有编程基础的看看就行
python官方文档
b) 前端三件套 -
引入所需的库
import bs4 #网页解析,获取数
import re #正则表达式,进行文字匹配
import urllib #制定URL,获取网页数据
import xlwt #进行excel操作
import sqlite3 #进行sqlite数库操作
二、工作逻辑
1、爬取网页
import urllib.request
def getHtml(url):
head = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
}
# 封装请求体
request = urllib.request.Request(url, headers=head)
html = ""
try:
# 发送请求
response = urllib.request.urlopen(request)
# decode:对文件进行编码,就是格式化
html = response.read().decode("utf-8")
except urllib.error.URLError as e:
if hasattr(e, "code"):
print(e.code)
return html
url = "https://movie.douban.com/top250?start=26"
res = getHtml(url)
print(res)
2、解析数据
bs4用于将将文档解析未文档树,便于提取想要的部分
re 正则表达式就是更加详细的提取想要的部分
打个比方:bs4将数据分类管理,拿到一部分数据,re再根据正则表达在该部分上提取所要的部分
bs4
# html爬取的文档
bs = BeautifulSoup(html, "html.parser") # 造个靓汤
# 遍历文档获取目标部分
bs.find_all("div", class_="item") # 所需模块为 <div class="item">
re
re库学习
3、保存数据
import xlwt
workbook = xlwt.Workbook(encoding="utf-8") #创建workbook对象
worksheet = workbook.add_sheet('sheet1') #创建工作表
worksheet.write(0, 0, 'hello') #将数据写入到第一个表,前两个是数据写入位置的坐标(x,y),第三个是数据
workbook.save('demo1.xls') #保存数据表
三、案例
1.豆瓣电影top250
# 时间 2021/10/11 16:33
# 豆瓣电影top250
import urllib.request
from bs4 import BeautifulSoup # 网页解析,获取数据
import re # 正则表达式,进行文字匹配`
import urllib.request, urllib.error # 制定URL,获取网页数据
import xlwt # 进行excel操作
# 1.爬取目标网页
def getHtml(url):
# 封装请求体
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
}
request = urllib.request.Request(url=url, headers=header)
# 请求网站
response = urllib.request.urlopen(request)
# 解码文档
html = response.read().decode('utf-8')
return html
# 正则表达
findLink = re.compile(r'<a href="(.*?)">') # 电影连接
findImg = re.compile(r'<img.*src="(.*?)"', re.S) # 电影海报
findTitle = re.compile(r'<span class="title">(.*)</span>') # 电影名
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>') # 电影评价
findRatingNum = re.compile(r'<span>(\d*)人评价</span>') # 电影评价人数
findInq = re.compile(r'<span class="inq">(.*)</span>') # 电影评论
findBd = re.compile(r'<p class="">(.*?)</p>', re.S) # 电影导演
# 2.解析文档获取数据
def findRequest(url):
# 存储所有数据
dataList = []
for i in range(0, 10):
askUrl = url + str(i * 25)
# 爬取网页
html = getHtml(askUrl)
# 获得一碗靓汤 参数1:解析对象 参数2:解析引擎 返回结果:dom文件树
bs = BeautifulSoup(html, "html.parser")
# 先定位到电影详情部分,div元素且class值为item
for item in bs.find_all("div", class_="item"):
# 存储每一页的数据
data = []
item = str(item) # 字符化,用于正则获取内容
link = re.findall(findLink, item)[0] # 电影连接
data.append(link)
img = re.findall(findImg, item)[0] # 电影海报
data.append(img)
title = re.findall(findTitle, item)
# 因为有中文英文名(不一定有英文名),所以分类讨论
# 1.中文名一定有
data.append(title[0])
# 2.是否有英文名
if len(title) == 2:
data.append(title[1].replace("/", ""))
else:
data.append(" ")
rating = re.findall(findRating, item)[0] # 电影评价
data.append(rating)
ratingNum = re.findall(findRatingNum, item) # 电影评价人数
data.append(ratingNum)
inq = re.findall(findInq, item) # 电影评论
if len(inq) != 0:
data.append(inq[0].replace("。", ""))
else:
data.append(" ")
bd = re.findall(findBd, item)[0] # 电影导演
bd = re.sub('<br(\s+)?/>(\s+)?', "", bd)
bd = re.sub('/', "", bd)
data.append(bd.strip()) # strip()去掉空格
dataList.append(data) # 存储一个电影
return dataList
# 保存数据
def saveData(dataList):
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):
data = dataList[i]
for j in range(0, 8):
sheet.write(i + 1, j, data[j]) # 数据
book.save("豆瓣电影Top250.xls") # 保存
# 主程序
# 目标网址
dataList = []
url = "https://movie.douban.com/top250?start="
# 解析数据
dataList = findRequest(url)
# 保存数据
saveData(dataList)
2.图片下载
# 编写 Lzk
# 时间 2021/10/12 14:09
import re
import urllib.request
from bs4 import BeautifulSoup # 网页解析,获取数据
import os
import requests
findLink = re.compile(r'<a class="thumb-link" href="(.*?)" rel="nofollow">') # 详情链接
findName = re.compile(r'<h2><a href=".*">(.*?)</a></h2>') # 图集名
findImg = re.compile(r'<img.*src="(.*?)".*/>') # 图片链接
# 图片存放的绝对地址
fileUrl = "E:\pycharm\爬虫图片"
# 目标网址
url1 = "https://www.jdlingyu.com/tag/jk%e5%88%b6%e6%9c%8d"
header = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36"
}
# 封装请求体
request1 = urllib.request.Request(url=url1, headers=header)
# 发送请求
response1 = urllib.request.urlopen(request1)
# 解码
html1 = response1.read().decode('utf-8')
# 解析成文档树
dom1 = BeautifulSoup(html1, "html.parser")
# 遍历文档树
for item1 in dom1.find_all("li", class_="post-list-item item-post-style-1"):
# 字符化文档,便于正则提取
item1 = str(item1)
url2 = re.findall(findLink, item1)[0] # 详情页链接
fileName = re.findall(findName, item1)[0] # 图集名
# 拼接文件名
fileName = fileUrl + '\\' + fileName
# 创建文件夹存放该图集下的图片
if not os.path.exists(fileName):
os.makedirs(fileName) # 如果没有这个path则直接创建
# 进入图集详情页
request2 = urllib.request.Request(url=url2, headers=header)
response2 = urllib.request.urlopen(request2)
html2 = response2.read().decode('utf-8')
dom2 = BeautifulSoup(html2, "html.parser")
for item2 in dom2.select("div[class='entry-content']>img"):
item2 = str(item2)
for item3 in re.findall(findImg, item2):
imgData = requests.get(url=item3, headers=header).content # 获取图片二进制数据
# 将图片连接用/分隔开来,取最后的后缀为图片名
imgName = item3.split('/')[-1]
with open(fileName + '\\' + imgName, mode='wb') as f:
f.write(imgData)
print('保存完成:', imgName)
不知道为什么有些图片下载后文件格式不支持
【推荐】
爬取动态页面数据
【mysql】
import pymysql
#连接数据库
conn = pymysql.connect(host = '127.0.0.1' # 连接名称,默认127.0.0.1
,user = 'root' # 用户名
,passwd='password' # 密码
,port= 3306 # 端口,默认为3306
,db= 'vueblog' # 数据库名称
,charset='utf8' # 字符编码
)
cur = conn.cursor() # 生成游标对象
sql = "xxx" #sql语句
try:
cur.execute(sql) # 执行sql语句
# data = cur.fetchall() # 查询语句通过fetchall方法获得数据
conn.commit() # 提交到数据库执行 # 增删改需要提交
except:
conn.rollback()# 如果增删改发生错误则回滚
conn.close() # 关闭数据库连接