目录
前言
一、爬虫是什么?
二、简要介绍要使用的库
1. urllib 库
2.BeautifulSoup 库
三、爬取的完整代码
总结
前言
本文是作者学习爬虫内容后进行的一次实战并总结,也只是总结,没有用于其他用途(⊙o⊙)…
一、爬虫是什么?
既然学习爬虫了,要先明白爬虫是个啥?
百度一下:
网络爬虫是一种自动获取网页内容的程序,是搜索引擎的重要组成部分。网络爬虫为搜索引擎从万维网下载网页。
学习时视频里的老师简单概述的:
客户端给服务器发送一个请求,服务器接收后,给出一个响应,这个响应是以html格式输出的,里面就是咱们要爬取的内容(用代码模仿正常的浏览器去向服务器发送请求,服务器响应的内容就是咱们要爬取的),可以看下图,更生动一些。
二、简要介绍要使用的库
1. urllib 库
urllib 库是 python 内置的 HTTP 请求库,包括以下模块:
- urllib.request 请求模块
- urllib.error 异常处理模块
- urllib.parse url 解析模块
- urllib.robotparser robots.txt 解析模块
这个网站是get请求方式(按f12,点击网络,刷新,可以看到发出和响应的信息)
import urllib.request
# 获取一个get请求
response = urllib.request.urlopen("https://xxxx") # 网站的地址url
print(response.read().decode("utf-8")) # 获取网页源码并转码
代码结果输出如下(只截取部分)
上面是get请求,那post请求呢?
如下:
import urllib.request
import urllib.parse
url = "http://httpbin.org/post"
cookie = '''
JSESSIONID=1C56AA5DBE020FEAB6C50F7FDDE68110
'''
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
}
# 加上头部信息,不容易被查出是爬虫,按f12,点击网络,刷新,可以看到所有的请求信息,User-Agent直接复制过来
data = bytes(urllib.parse.urlencode({"Cookie":cookie}),encoding='utf-8')
# #模拟登陆获取信息,字典的数据是账号密码、cookie等
req = urllib.request.Request(url=url,data=data,headers=headers,method="POST")
response = urllib.request.urlopen(req)
print(response.read().decode('utf-8'))
代码结果输出如下(没有headers时的结果)(出现这个结果就是post请求是成功的):
注意:看上图的User-Agent这个后面是Python..,这是因为我没有带headers信息,所以如果不带这个headers,在真实的爬取中,会百分百被识别是爬虫的。
带上headers在爬取一次:
可以看到User-Agent这个是咱们自己的浏览器信息,cookie也带上了,这样网站不容易查出咱们是爬虫。
2.BeautifulSoup 库
BeautifulSoup 是 Python 的一个第三方库,可以用来解析 html 数据,我们使用它的主要功能就是从网页抓取解析数据:
- BeautifulSoup 提供一些简单的、python 式的函数用来处理导航、搜索、修改分析树等功能
- BeautifulSoup 通过解析文档为用户提供需要抓取的数据
- BeautifulSoup 自动将输入文档转换为 Unicode 编码,输出文档转换为 utf-8 编码
BeautifulSoup 将复杂的 HTML 文档转换成一个复杂的树形结构,每个节点都是 Python对象。所有对象可以归纳为4种类型:
Tag:HTML 或者 XML 中的标签
NavigableString:标签中的文本内容(不包含标签)
BeautifulSoup:BeautifulSoup 对象表示一个文档的全部内容,支持遍历文档树和搜索文档树
Comment:HTML和XML中的注释
利用 BeautifulSoup() 将上面读取到的 html 文档进行转换,如下:
import urllib.request
from bs4 import BeautifulSoup
response = urllib.request.urlopen("https://xxx") # 网站的地址
html = response.read().decode("utf-8")
bs = BeautifulSoup(html,'html.parser') # 用于解析获取到的源码
获得源码后,BeautifulSoup给解析完页面后,使用find_all()来进行文档的搜索。
find_all()为搜索文档树,搜索当前tag的所有tag子节点,并判断是否符合过滤器的条件。返回值类型是 bs4.element.ResultSet,即返回的是多个该对象的集合,可以用for循环遍历,完整的语法如下:
find_all( name, attrs, recursive, string, **kwargs)
参数意义如下:
name:查找所有名字为 name 的 tag。
attr:tag的属性(即标签的属性)
string:搜索文档中string字符串的内容
recursive: 调用 tag 的 find_all() 方法时,BeautifulSoup 会检索当前 tag 的所有子孙节点;如果只想搜索tag的直接子节点,可以使用参数 recursive=False
首先分析一下网页,找到自己需要的信息,例如:爬取教师的信息,可以看到信息在table class="listTable"的下面,而其他的我们并不需要。
爬取到我们需要的信息如下:
接着分析会发现,每个老师的信息都单独在一个<tr id="line_u5_*">中,*是一个数字,应该是序号,接着一步一步靠近自己需要的信息即可。
三、爬取的完整代码
代码的整体思想就是:
1.分析出网址的规律,发现只有页数的变化,所以不变的一部分就赋值在baseurl,爬取每页的时候,在进行补全。
2.函数askUrl()用来一页一页的解析页面,并返回得到的页面,给getData()函数,此函数就是获取需要的信息,并保存到一个列表中,最后返回到saveDate()。
3.saveDate()用拿到的列表,来保存起来数据,这里是保存到了Excel中。
# codeing = utf-8
from bs4 import BeautifulSoup
import xlwt
import re
import urllib.request, urllib.error
b = 0 # 网页的内容 不是很规律,定义个变量
def main():
baseurl = 'https://xxxx' # 目标网站
datalist = getData(baseurl)
saveDate(datalist)
def getData(baseurl): # 获取数据
datalist = []
for i in range(1,8): # 要爬取很多页面,这个是循环,配上baseurl用的,就是找到每一页的网址
if i == 7:
url = baseurl + '.htm'
b = 20
elif i == 1:
b = 20
url = baseurl + '/' + str(i) + '.htm'
else:
b = 38
url = baseurl + '/' + str(i) + '.htm'
html = askUrl(url)
# soup = BeautifulSoup(str(html), 'html.parser')
for i in range(0,b):
data = []
soup = BeautifulSoup(str(html), 'html.parser')
html1 = soup.find_all(id="line_u5_"+str(i)+"")
soup = BeautifulSoup(str(html1),'html.parser')
# print(soup)
list = soup.find_all('td')
# print(soup)
for j in range(0,7):
data.append(list[j].get_text().replace(' ',''))
datalist.append(data)
return datalist
def askUrl(url): # 页面解析
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
'accept':'text / html, application / xhtml + xml, application / xml;q = 0.9, image / avif, image / webp, image / apng, * / *;q = 0.8, application / signed - exchange;v = b3; q = 0.9'
} # 头部信息,头部信息越全面,不容易被识别出
cookie = '''
JSESSIONID=1C56AA5DBE020FEAB6C50F7FDDE68110
'''
data = bytes(urllib.parse.urlencode({'Cookie':cookie}),encoding='utf-8')
request = urllib.request.Request(url=url, data=data, headers=headers, method='GET')
response = urllib.request.urlopen(request)
html = response.read().decode('utf-8') # 未处理的全部页面
soup = BeautifulSoup(html,'html.parser') # 一次解析页面
html = soup.find_all('table',class_='listTable') # 筛选出需要的
# soup = BeautifulSoup(str(html),'html.parser')
return html
# for i in range(1,20):
# html = soup.find_all('tr',id="line_u5_"+str(i)+"")
def saveDate(datalist): # 保存数据,这里保存到了Excel中了
k=0
book = xlwt.Workbook('encoding = utf-8') # 获取工作薄
sheet = book.add_sheet('信息',cell_overwrite_ok=True) # 增加个表
col = ['姓名','性别','民族','学历','职位','专业一','专业二']
for i in range(0,7):
sheet.write(0,i,col[i]) # 单元格是从下表0,0开始的
for list in datalist:
k = k+1
for j in range(0,7):
sheet.write(k,j,list[j])
book.save('信息.xls')
if __name__ == main():
main()
运行后,你的PyCharm里的左侧的项目栏里会出现信息这个表,就是爬取后保存的。
总结
1.上述只能爬取一些反爬机制不强的网站,例如爬取异步加载的网站还需要调整几个部分,接下来会写怎么爬取异步加载的网站。
2.在爬虫的时候,先爬取一页,并用html的形式保存这一页,然后就先不要爬取了,只需要在保存的这一页上实验就可以了,不然你调整一下,爬取一下,对方的网站识别出爬虫,是会封你的IP的,还有是用for循环获取页面的时候,每获取一页设置停顿一会,这样对方网站认为你是正常的用户而不是爬虫,不然一个for循环获取好几页,会被识别出来是爬虫的。