爬虫:模拟浏览器上网,然后让其去互联网抓取数据的脚本。
requests模块
python中原生的一款基于网络请求的模块,功能强大,简单便捷,效率极高。
作用:模拟浏览器发送请求。
requests模块的编码流程:
- 指定url
- 发起请求
- 获取响应数据
- 持久化储存
get请求
import requests
# 指定url
url = 'https://buyunaihe.cn/'
# UA伪装
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 处理url携带的参数
param = {
's':'python'
}
# 发起请求:使用get方法发起请求,该方法返回一个响应对象
response = requests.get(url,params=param,headers=header)
# 获取响应数据:通过调用响应对象的text属性,返回响应对象中储存的字符串形式的响应数据(页面源码)
text = response.text
# 存储数据
with open('demo/data.txt','w',encoding='utf-8') as fp:
fp.write(text)
post请求
import json
import requests
# 指定url
url = 'https://fanyi.baidu.com/sug'
# UA伪装
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 处理url携带的参数
data = {
'kw':'dog'
}
# 发起请求:使用post方法发起请求,该方法返回一个响应对象
response = requests.post(url,data=data,headers=header)
# 获取响应数据:json()方法返回的是obj(如果确定响应数据是json类型的,才能使用json)
obj = response.json()
# 存储数据
fp = open('demo/data.txt','w',encoding='utf-8')
json.dump(obj,fp,ensure_ascii=False)
数据解析
正则解析
import re
print(re.findall(r'\d+','ab12cd3'))
# ['12', '3']
result = re.finditer(r'\d+','ab12c3')
for item in result:
print(item.group())
# 12
# 3
bs4解析
1.实例化一个BeautifukSoup对象,并将页面源码加载到该对象中
2.通过调用BeautifulSoup对象相关属性或者方法进行标签定位和数据提取
解析器 | 使用方法 | 优势 | 劣势 |
---|---|---|---|
Python标准库 | BeautifulSoup(markup,"html.parser") | Python的内置标准库、执行速度适中、文档容错能力强 | Python 2.7.3及Python 3.2.2之前的版本文档容错能力差 |
xml HTML解析器 | BeautifulSoup(markup, "lxml") | 速度快、文档容错能力强 | 需要安装C语言库 |
lxml XML解析器 | BeautifulSoup(markup, "xml") | 速度快、唯一支持XML的解析器 | 需要安装C语言库 |
html5lib | BeautifulSoup(markup, "html5lib") | 最好的容错性、以浏览器的方式解析文档、生成HTML5格式的文档 | 速度慢、不依赖外部扩展 |
通过以上对比可以看出,lxml解析器有解析HTML和XML的功能,而且速度快,容错能力强,所以推荐使用它。
import requests
from bs4 import BeautifulSoup
# 指定url
url = 'https://fanyi.baidu.com'
# UA伪装
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# BeautifulSoup对象实例化
# 1.将本地的html文档加载到BeautifulSoup对象
with open('./test.html','r',encoding='utf-8') as fp:
soup = BeautifulSoup(fp,'lxml')
# 2.将互联网上获取的页面源码加载到该对象
response = requests.get(url,headers=header)
page_text = response.text
soup = BeautifulSoup(page_text,'lxml')
提供用于数据解析的方法和属性
-
soup.tagName:返回文档中第一次出现tagName对应的标签
-
soup.find()
- soup.find('tagName'):等同于soup.tagName
- soup.find('tagName',class_/id/attr =''):属性定位
-
soup.find_all():返回所有,其余和find()相同
-
soup.select('某种选择器'):返回一个列表
xpath解析
最便捷且最高效的解析方式
1.实例化一个etree对象,且需要将被解析的页面内源码加载到该对象。
2.调用etree对象的xpath方法结合着xpath表达式实现标签的定位和内容的捕获。
import requests
from lxml import html
# 指定url
url = 'https://fanyi.baidu.com/sug'
# UA伪装
header = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 1.将本地的html文档加载到etree对象
etree = html.etree.pase('./text.html')
# 2.将互联网上获取的页面源码加载到该对象
response = requests.get(url,headers=header)
page_text = response.text
etree = html.etree.HTML(page_text)
样例
正则
爬取崩坏3所有女武神装甲图片
import re
import os
import requests
# 创建文件夹
if not os.path.exists('./bh3'):
os.mkdir('./bh3')
# 指定url
URL = 'https://bh3.mihoyo.com/valkyries'
# UA伪装
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 使用通用爬虫对url源码进行爬取
page_text = requests.get(URL, header).text
# 数据解析
# 正则匹配式
ex = r'<a href="(.*?)">'
url_list = re.findall(ex, page_text)
# 发现有且仅有第一个链接是不需要的
url_list.pop(0)
ex1 = r'''<div class="name">
(.*?)
</div>'''
ex2 = r'<div class="big-img"><img src="(.*?)">'
for url in url_list:
sec_url = 'https://bh3.mihoyo.com' + url
text = requests.get(sec_url, header).text
# 图片名称
name = re.findall(ex1, text)[0]
# 图片地址
src = re.findall(ex2, text)[0]
# 图片数据
data = requests.get(src, header).content
# 存储路径
path = './bh3/' + name+'.png'
with open(path,'wb') as f:
f.write(data)
print(name)
bs4
爬取17k小说畅销榜前100
import csv
import requests
from bs4 import BeautifulSoup
from lxml import html
# 指定url
url = 'https://www.17k.com/top/refactor/top100/01_subscribe/01_subscribe__top_100_pc.html'
# UA伪装
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.36'
}
# 实例化对象
response = requests.get(url, headers=header)
response.encoding='utf-8'
soup = BeautifulSoup(response.text, 'lxml')
# 数据解析
tr_list = soup.select('body > div.Main.Top100 > div.content.TABBOX > div:nth-child(2) > div:nth-child(1) > table > tr')
# 获取表头
th_list = tr_list[0].select('th')
title = []
for th in th_list:
title.append(th.text)
infors = [title]
# 获取内容
tr_list.pop(0)
for tr in tr_list:
td_list = tr.select('td')
infor = []
for td in td_list:
infor.append(td.text)
infors.append(infor)
# 存储数据
with open('./top100.csv','w',encoding='utf-8-sig',newline='') as f:
writer = csv.writer(f)
for infor in infors:
writer.writerow(infor)
Comments | NOTHING