一、爬虫
通过编写程序来获取网上的资源
用程序模拟浏览器,输入一个网址,从该网址获取到资源或者内容
二、基础步骤
1.导包
from urllib.request import urlopen
2.写入网址
url = "http://www.xx.com"
3.打开网址
resp = urlopen(url)
4.读写并爬取文件然后读写
with open("mybaidu.html",mode="w",encoding="utf-8") as f:
f.write(resp.read().decode("utf-8"))
上最终代码:
from urllib.request import urlopen #打开一个网址
url = "http://www.xxx.com" #所要爬取的网址
resp = urlopen(url) #打开一个网址
with open("xxx.html",mode="w",encoding="utf-8") as f:
f.write(resp.read().decode("utf-8")) #读取 .decode("utf-8") 转码,使用万国码
print("over")
三、web请求过程
# 1.服务器渲染:在服务器那边直接把数据和html整合在一起。 统一返回给浏览器
# 在页面源代码中能看到数据
# 2.客户端渲染:
# 第一次请求只要一个html骨架。第二次请求拿到数据。进行数据展示
# 在页面源代码中,看不到数据
四、http协议
# 请求:
# 1.请求行 -> 请求方式(Get/Post)请求url地址
# 2.请求头 -> 放一些服务器需要的附加信息
# 3.请求体 -> 放请求参数
#
# 请求头中最常见的一些重要内容(爬虫需要):
# 1.UserAgent:请求载体的身份标识(用啥发送的请求)
# 2.Referer: 防盗链(这次请求是从哪个页面来的?反爬会用到)
# 3.cookie: 本地字符串数据信息(用户登录信息,反爬的token)
#
#响应:
# 1.状态行 -> 协议 状态码
# 2.响应头 -> 放一些客户端要使用的一些附加信息
# 3.响应体 -> 服务器返回的真正客户端要用的内容(HTML,json)等
#
# 响应头中一些重要的内容:
# 1.cookie: 本地字符串数据信息(用户登录信息,反爬的token)
# 2.各种神奇的莫名其妙的字符串(这个需要经验了,一般都是token字样,防止各种攻击和反爬)
#
# 请求方式:
# GET:
# POST:
五、Requests
1.安装requests
pip install requests
or
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
2.对于Get请求,获取搜索后的页面
import requests
query = input("请输入一个明星")
url = f"https://www.sogou.com/tx?query={query}"
headers = {
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3877.400 QQBrowser/10.8.4506.400"
}
resp = requests.get(url,headers=headers) #处理一个小小的反爬
print(resp)
print(resp.text)
3.对于Post请求,获取dog翻译后的JSON
import requests
# 这个url是输入翻译后最后一个sug包
url = "https://fanyi.baidu.com/sug"
s = input("请输入你要翻译的英文单词")
dat = {
"kw":s
}
#发送post请求,需要带参数
resp = requests.post(url , data = dat)
print(resp.json()) # 将服务器返回的内容直接处理成为json()
封装get参数
import requests
url = "https://movie.douban.com/j/chart/top_list"
# 重新封装参数
param = {
"type": "24",
"interval_id": "100:90",
"action":"",
"start": "0",
"limit": "20"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3877.400 QQBrowser/10.8.4506.400"
}
#发送get请求
resp = requests.get(url=url , params = param,headers=headers)
print(resp.json()) # 将服务器返回的内容直接处理成为json()
resp.close()
五、数据解析
- re解析
- bs解析
- xpath解析
1.re解析 正则表达式
常用元字符
常用元字符 | 语义 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或下划线 |
\s | 匹配任意的空字符 |
\d | 匹配数字 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结尾 |
\W | 匹配非字母或数字或下划线 |
\D | 匹配非数字 |
\S | 匹配非空字符 |
alb | 匹配字符a或字符b |
() | 匹配括号内的表达式,也表示一个组 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中字符的所有字符 |
量词:控制前面的元字符出现的次数
量词 | 语义 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n次到m次 |
贪婪匹配和惰性匹配
字符 | 语义 |
---|---|
.* | 贪婪匹配 |
.*? | 惰性匹配 |
re模块的使用
import re
# findall,匹配字符串中所有的符号正则的内容
lst = re.findall(r"\d+","我的电话号是:10086,我的女朋友的电话是10010")
print(lst)
# finditer:匹配字符串中所有的内容(返回迭代器),通过.group()拿到内容数据
it = re.finditer(r"\d+","我的电话号是:10086,我的女朋友的电话是10010")
for i in it:
print(i.group())
# search返回的结果是match对象,找到一个结果就返回,通过.group()拿到数据
s = re.search(r"\d+","我的电话号是:10086,我的女朋友的电话是10010")
print(s.group())
# match从头开始匹配,通过.group()拿到数据
m = re.match(r"\d+","10086,我的女朋友的电话是10010")
print(m.group())
# 预加载正则表达式
obj = re.compile(r"\d+")
ret = obj.finditer("我的电话号是:10086,我的女朋友的电话是10010")
for i in ret:
print(i.group())
import re
s = """
<div class='jay'><span id='1'>郭麒麟</span></div>
<div class='jj'><span id='2'>宋铁</span></div>
<div class='jolin'><span id='3'>大聪明</span></div>
<div class='sylar'><span id='4'>范思哲</span></div>
<div class='tory'><span id='5'>胡说八道</span></div>
"""
# re.S : 让.能匹配换行符
# (?P<wahaha>正则) : 可以单独从正则匹配的内容进一步提取
obj = re.compile(r"<div class='.*?'><span id='(?P<id>\d+)'>(?P<wahaha>.*?)</span></div>",re.S)
result = obj.finditer(s)
for i in result:
print(i.group("id"))
print(i.group("wahaha"))
re实战
# 1.定位到2021必看热片
# 2.从2021必看热片中提取到子页面的链接地址
# 3.请求子页面的链接地址,拿到我们想要的下载地址
import requests
import re
domain = "https://www.dytt89.com/"
resp = requests.get(domain,verify=False) # verify=False 去掉安全验证
resp.encoding = 'gb2312'
# print(resp.text)
# 拿到ul里面的li
obj1 = re.compile(r"2021必看热片.*?<ul>(?P<ul>.*?)</ul>",re.S)
obj2 = re.compile(r"<a href='(?P<href>.*?)'",re.S)
obj3 = re.compile(r'◎片 名(?P<movie>.*?)<br />.*?<td '
r'style="WORD-WRAP: break-word" bgcolor="#fdfddf">'
r'<a href="(?P<download>.*?)">',re.S)
child_href_list = []
result1 = obj1.finditer(resp.text)
for it in result1:
ul = it.group("ul")
# 提取子页面链接
result2 = obj2.finditer(ul)
for itt in result2:
# 拼接子页面的url地址: 域名 + 子页面地址
child_href = domain + itt.group("href").strip("/")
child_href_list.append(child_href)
# 提取子页面的内容
for href in child_href_list:
child_resp = requests.get(href,verify=False)
child_resp.encoding = 'gb2312'
result3 = obj3.search(child_resp.text)
print(result3.group("movie"))
print(result3.group("download"))
break
resp.close()
2.Bs4解析
导包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple bs4
# 1.把页面源代码交给BeautifulSoup进行处理,生成bs对象
page = BeautifulSoup(resp.text,"html.parser") #指定html解析器
# 2.从bs对象中查找数据
# find(标签,属性=值)
# find_all(标签,属性=值)
bs4实战:
# 1.拿到页面代码,然后提取子页面的链接地址,href
# 2.通过href拿到子页面的内容,从子页面中找到图片的下载地址 img->src
# 3.下载图片
import requests
from bs4 import BeautifulSoup
import time
url = "https://umei.cc/weimeitupian/yijingtupian/"
domain = "https://umei.cc"
resp = requests.get(url)
resp.encoding = 'utf-8'
# print(resp.text)
# 把源代码交给bs
main_page = BeautifulSoup(resp.text,"html.parser")
alist = main_page.find("div",class_="TypeList").find_all("a")
# print(alist)
for a in alist:
href = domain + a.get("href") # 直接通过get就可以拿到属性的值
# 拿到子页面的源代码
child_page_resp = requests.get(href)
child_page_resp.encoding="utf-8"
child_page_text = child_page_resp.text
# 从子页面中拿到图片的下载路径
child_page = BeautifulSoup(child_page_text,"html.parser")
p = child_page.find("p",align="center")
img = p.find("img")
# print(img.get("src"))
src = img.get("src")
# 下载图片
img_resp = requests.get(src)
img_name = src.split("/")[-1] # 拿到url中最后一个/以后的内容
with open(img_name,mode="wb") as f:
f.write(img_resp.content)
print(img_name,"---------->over")
time.sleep(1)
print("all over")
resp.close()
3.Xpath
导包pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml
Xpath的顺序是从1开始数的,用[ ]来进行索引,@进行筛选
text()
表示输出文本
@href
表示拿到属性
实战:
# pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml
import requests
from lxml import etree
url = "https://so.680.com/fuwu.html?key=saas&init=1"
resp = requests.get(url)
# print(resp.text)
# 解析
html = etree.HTML(resp.text) # 加载HTML源码
# 拿到一个个小的盒模型,也就是某个服务商的div
divs = html.xpath('//*[@class="fws-pic-list"]/div')
# print(divs)
for div in divs: #每一个服务商的信息
price = div.xpath('//*[@class="fl money"]/text()')
title = div.xpath('//*[@class="searchtitle"]/text()')
com_name = div.xpath('//*[@class="vk-name"]/a/text()')
print(com_name)
print("-----------------------------")
resp.close()
Requests进阶
1.处理cookie
# 登录 -> cookie
# 带着cookie去请求url -> 拿到对应内容
# 使用session进行请求 -> session 可以认为是一连串的请求,在这个过程中cookie不会丢失
2.处理防盗链
梨视频实战(url的拼接加防盗链):
1.拿到contId
2.拿到videoStatus返回的json -> srcURL
3.srcURL里面拿到内容进行修改
4.下载视频
import requests
url = "https://www.pearvideo.com/video_1734427"
contId = url.split("_")[1]
videostatusUrl = f"https://www.pearvideo.com/videoStatus.jsp?contId={contId}&mrd=0.638220203007744"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3877.400 QQBrowser/10.8.4506.400",
# 防盗链 : 溯源,找到当前请求的上一级是啥
"Referer": "https://www.pearvideo.com/video_1734427"
}
resp = requests.get(videostatusUrl,headers=headers)
dic = resp.json()
srcUrl = dic["videoInfo"]["videos"]["srcUrl"]
systemTime = dic["systemTime"]
srcUrl = srcUrl.replace(systemTime,f"cont-{contId}")
print(srcUrl)
# https://video.pearvideo.com/mp4/adshort/20210707/1635749702305-15713455_adpkg-ad_hd.mp4
# https://video.pearvideo.com/mp4/adshort/20210707/cont-1734427-15713455_adpkg-ad_hd.mp4
下载视频
with open("a.mp4",mode="wb") as f:
f.write(requests.get(srcUrl).content)
resp.close()