爬虫的四大步骤
- 获取网页源代码
- 获取标签(tag)
- 正则表达式匹配
- 保存数据
获取网页源代码
常用的有urllib的python自带库还有第三方库requests
- urllib库
#导包
import os
import time
import urllib.request
#爬取指定url网页
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
request = urllib.request.Request(url=surl,headers = header)#伪装成浏览器访问方式
html = urllib.request.urlopen(request)#打开请求信息所得数据
htmltxt = html.read()#读取网页数据 转换成字符串类型
#print(type(htmltxt))
#print(htmltxt)
- requests库
#请求
import requests
url = 'https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=10:0&action='#网址
headers = {user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'}#请求头,用于伪装成浏览器用户访问
html = requests.get(url=url,headers=headers)#发出一个请求
#响应
print(html.text)#将请求所得数据转换成字符串数据,与urllib库的html.read()作用相同
获取标签(tag)
给大家说一下爬虫的对象变化:
首先请求得到一个response对象,然后urlopen()打开,read()方法读取,用BeautifulSoup解析成改对象,然后改对象有find(),find_all()等方法去获取网页具体标签下的数据,生成的是标签(tag)对象,tag对象可以调用这两个方法来一层一层的爬取网页,或者用正则表达式爬的更细更符合自己的要求一些。
解析要用到BeautifulSoup这个库,它的用法大家可以参考大佬博主的这篇博文:https://blog.csdn.net/weixin_43930694/article/details/90142678?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
#解析-》基础的简单的该库的方法,详细的参考上面给出的博文或者自行查看
from bs4 import BeautifulSoup
soup = BeautifulSoup(html.text,'html.parser')#soup是个BeautifulSoup对象,参数第二个是python自带的解析库,也可以用第三方库,自行csdn
items = soup.find('ul',class_ = 'nav_list').find('ul').find_all('li') #一层一层往下爬
for item in items:
kind = item.find('a')
print('分类:'+kind.text.strip())
正则表达式匹配
参考以前写的或者自行百度:自己写的正则和一些常用函数用法
正则表达式的一些查询方法
保存数据
一般都是爬下来保存成文档或者json格式或者别的数据方法比较多,案例用的是sqlite3数据库和excel表格保存到。l
案例
有个错误就是index超出范围,然后我把循环里面改大了一点,但是我爬不了豆瓣,给我封了。难过。
这是错误和运行结果:
from bs4 import BeautifulSoup
import urllib.request,urllib.error
import re
import sqlite3
import xlwt#进行excel操作
def main():
baseUrl = "http://movie.douban.com/top250?start="
#爬取网页,解析数据
dataList = getData(baseUrl)
savePath = ".\\豆瓣电影Top250.xls"
#savePath = "movies.db"
#保存数据
saveData(dataList,savePath)
#savedb (dataList,savePath)
#------正则表达式------#
findLink = re.compile(r'<a href="(.*?)">',re.S) #链接
findName = re.compile(r'<span class="title">(.*?)</span>',re.S) #电影名字
findRating = re.compile(r'<span class="rating_num" property="v:aerage">(.*?)</span>',re.S) #评分
findInq = re.compile(r'<span class="inq">(.*?)</span>',re.S) #下面小标题
findCount = re.compile(r'<span>(.*?)人评价</span>',re.S) #评分人数
findInf = re.compile(r'<p class="">(.*?)</p>',re.S) #电影信息
#---爬取网页---#
def getData(baseUrl):
dataList = []
for i in range(10):
html = askUrl(baseUrl + str(i * 25))
#每条解析数据
bs = BeautifulSoup(html,'html.parser')
for item in bs.find_all('div',class_='item'):
data = []
item = str(item)
#链接
link = re.findall(findLink,item)[0]
#名字
name = re.findall(findName,item)
if len(name) == 1:
cName = name[0]
fName = " "
else:
name[1] = name[1].replace("/","")
cName = name[0]
fName = name[1]
#评分
rating = re.findall(findRating,item)[0]
#标题
inq = re.findall(findInq,item)
if len(inq) < 1:
inq = " "
else:
inq = inq[0]
#评分人数
racount = re.findall(findCount,item)[0]
#电影信息
inf = re.findall(findInf,item)[0]
inf = re.sub("...<br(\s+)?/>(\s?)"," ",inf)
inf = re.sub("/"," ","inf")
inf = inf.strip()
#添加一部电影的信息到data
data.append(link)
data.append(cName)
data.append(fName)
data.append(rating)
data.append(inq)
data.append(racount)
data.append(inf)
dataList.append(data)
return dataList
#爬取指定的url
def askUrl(url):
head = {"User-Agent" : ""}
request = urllib.request.Request(url = url,headers = head)
http = " "
try:
response = urllib.request.urlopen(request)
http = response.read().decode('utf-8')
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e, "reson"):
print(e.reson)
return http
#保存数据
def saveData(dataList,savePath):
woke = xlwt.Workbook('utf-8,style_compression=0')#创建一个工程,参数:编码样式压缩效果
sheet = woke.add_sheet('豆瓣电影Top250',cell_overwrite_ok = True)#创建一个表,参数:表名,覆盖原单元格的参数
#列名
col = ('链接','中文名字','英文名字','评分','标题','评分人数','概括')
#遍历列名,并写入
for i in range(7):
sheet.write(0,i,col[i])
#遍历数据并写入
for i in range(0,251):
for j in range(7):
sheet.write(i+1,j,dataList[i][j])
print("第%n条数据:"%(i+1))
#保存数据到保存路径
woke.save(savePath)
print("保存完毕!")
#保存到数据库
def savedb(dataList,dataPath):
initdb(dataPath)#新建表
conn = sqlite3.connect(dataPath)#建立连接
cur = conn.cursor()#建立游标
#开始保存数据
for data in dataList:
for index in range(len(data)):
#在每条数据的两端加上双引号
data[index] = str('"' + data(index) + '"')
#用 , 拼接数据
newstr = ','.join(data)
#sql语句
sql = "insert into movie(info_link,cname,fname,rating,inq,racount,inf)values(%s)" %(newstr)
print(sql)
#执行sql
cur.excute(sql)
#提交事务
conn.commit()
cur.close()#关闭游标
conn.close()#关闭连接
print('保存完毕!')
#新建sqlite3的表
def initdb(dataPath):
conn = sqlite3.connect(dataPath)
cur = conn.cursor()#打开游标
sql = '''
create table movie(
id Integer primary key autoincrement,
nfo_link text,
name varchar,
name varchar,
ating varchar,
nq text,
acount varchar,
nf text
)
'''
cur.execute(sql)
conn.commit()
cur.close()
conn.close()
if __name__ == '__main__':
main()