Python学习日记(爬虫)

一、爬虫
通过编写程序来获取网上的资源
用程序模拟浏览器,输入一个网址,从该网址获取到资源或者内容

二、基础步骤
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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值