# Spider-Learn **Repository Path**: wzxnb/spider-learn ## Basic Information - **Project Name**: Spider-Learn - **Description**: 记录复习爬虫的过程,除了爬一般网页的文字对象和图片对象,还涉及了ins的图片分析和爬取,在Application3中涉及到了随机验证码的生成,以及分析验证码;Application5,6使用了多线程来爬取图片;Application7主要研究爬去抖音用户最近视频和单个无水印视频。 - **Primary Language**: Python - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2020-12-17 - **Last Updated**: 2022-09-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 爬虫回顾 > 此库仅作为个人复习爬虫时的记录, 不得作为其他用途 ## 1. Application1_request * 主要使用`requests`对**整个**页面或者**Ajax**数据进行爬取后再进行分析 **主要步骤** 1. 指定`url` 2. 封装参数到字典中 3. `UA`伪装 4. 获取爬取信息 5. 处理信息 ## 2. Application2_data_analysis * 爬取页面中指定内容 **数据解析分类:** - 正则🚽 > 对爬取到的数据进行字符串的正则匹配, 取出对应数据 - bs4👱‍♀️ > * 实例化`beautifulSoup`对象,并将页面源码加载到当前对象中 > * 通过调用该对象中的相关属性或者方法来实现标签定位和数据提取 * `soup.TagName`: 返回`html`中第一次出现的tagName对应的标签🏷 * `soup.find(tagName, class_)`利用属性来定位标签 * `soup.find_all(tagName)`返回找到的所有标签 * `soup.select(选择器)`返回按选择器找到的标签 * `soup.select("div > ul > li a")`可以按层级索引到标签(``css规范``) * 返回值可以用一下三种方法来获取标签中的内容 * `text`: 获取到标签下所有的文本内容 * `string`: 获取到标签下直系的内容 * `get_text()`: 获取到标签下所有的文本内容 * `soup.a['href']`: 使用中括号的方法获取到属性值 - xpath(**)🌹 > * 实例化一个etree的对象, 且需要将被解析的页面源码数据加载到该对象中 > * 调用etree对象中的xpath对象结合xpath表达式实现标签的定位和内容的捕获 * ``/``表示从根节点开始寻找 * `//`表示多个层级 * `//div[@class=""]-->tag[@attributeName=""]`实现属性定位 * `"//div[@class='song']/p[3]"`实现索引定位, 索引从`1`开始 * 取文本 * `//div[@class='tang']//li[5]/a/text()`只能获取直系内容 * `//div[@class='tang']//text()`获取标签下所有内容 * 取属性 * `//div[@class='song']/img/@src`取出属性值 * 在使用局部解析的时候需要在`xpath`前加上`.` **数据解析原理**: > 解析局部的文本内容都会在标签之间或者标签对应的属性中进行存储 1. 进行指定标签的定位 2. 标签或者标签对应的属性中存储的数据值进行提取 ## 3. Application3_verification_code > 应对反扒机制: 验证码 > > * 使用第三方平台实现验证码识别 ### update later ## 7. Application7_Tiktok > 爬取抖音用户视频 > > * 单个视频无水印 > * 单个用户最近所有视频 ### 7.1 single video without label 1. 初次访问链接可得到当前视频唯一的标识码即`video/*******/` 2. 得到该`unique code`后加上前缀得到视频链接 3. 修改链接中参数, 将`playwm`替换为`play`得到无水印地址 4. 无水印地址只能通过手机访问, 访问时头部信息改为`ios`或者`Android` 5. 保存视频为二进制文件 ```python # Author : CoffeeChicken # Date : 2020-10-04 13:16 # Function : 演示 抖音去水印 import requests import re import json # 抖音地址 url_list = ['https://v.douyin.com/JCbFdsJ/'] # 请求地址获取视频哈希码 for url in url_list: est1 = requests.get(url) uq = re.findall('video/(\d+)/', str(est1.url))[0] # print("哈希码: ",uq) # 得到哈希码后获取视频地址 ur11 = f'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids={uq}' est2 = requests.get(ur11).text js1 = json.loads(est2) # print("js1====>", js1) # 找到视频链接后将参数修改获得无水印地址 url3 = str(js1['item_list'][0]['video']['play_addr']['url_list'][0]).replace('playwm', 'play') # print("url====>",url3) # 获得标题 title = str(js1['item_list'][0]['desc']) print(title) # 无水印地址访问时需要用移动端头信息 headers = { 'User-Agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko)' ' Chrome/66.0.3329.0 Mobile Safari/537.36' } # est=requests.get(url=url3,headers=headers).url # 发起请求获得无水印视频 est = requests.get(url=url3, headers=headers) with open(f'{title}.mp4', 'wb') as f: f.write(est.content) ``` ### 7.2 save recent videos > 保存用户最近所有视频 1. 访问视频博主用户界面 2. 获取重定向后地址中的`sec_uid`即用户唯一标识符 3. 拼接用户详情页地址后获取用户视频列表 4. 获取到无水印地址后发起请求 5. 为当前用户创建文件夹 6. 保存视频为二进制文件 ```python # Author : CoffeeChicken # Date : 2020-12-02 21:12 # Function : 演示 拼接url import re import os import requests import json headers = { 'User-Agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko)' ' Chrome/66.0.3329.0 Mobile Safari/537.36' } url = "https://www.iesdouyin.com/web/api/v2/aweme/post/?sec_uid=" # 用户页面地址 user_url = "https://v.douyin.com/JCASaYR/" # 初次请求 response = requests.get(user_url) # 获取重定向后地址 redirect_url = response.url # print(redirect_url) # 正则匹配规则 reg = ".*sec_uid=(.*?)&" # 获取到sec_uid sec_uid = re.match(reg, redirect_url).group(1) # 拼接最终url url += sec_uid # 设置一个较大的视频数 url += "&count=10000" # 多次遍历 for _ in range(100): result = requests.get(url, headers) json_str = result.text json_type = json.loads(json_str) length = len(json_type["aweme_list"]) if length != 0: print(length) # 获取所有视频地址 for item in json_type["aweme_list"]: # 获取视频博主昵称 nickname = item["author"]["nickname"] # 当前视频标题 title = item['desc'] # 无水印视频地址 video_url = item["video"]["play_addr"]["url_list"][0] # print(video_url) est = requests.get(url=video_url, headers=headers) # 为该用户创建文件夹 if not os.path.exists(nickname): os.mkdir(nickname) # 保存视频 with open(f'{nickname}/{title}.mp4', 'wb') as f: f.write(est.content) break ```