赞
踩
创作于
本人已经撰写过几篇关于某音的文章:
因为某音推出了网页版本,本次使用Selenium配合mitmdump实现全自动抓取某音网页视频数据,可以解析出视频名称、视频地址、无水印地址等…。
下图是自动化抓取过程,某音一次加载6个视频,当用户刷到第4个视频时,开始请求下一次数据,抓取此请求接口即可。
下图为结果数据库(MongoDB)
通过Selenium向webdriver发出指令,进而对Chrome进行控制,比如打开网站主页,模拟按下键盘按键,实现视频的切换,产生数据的加载,异步开启mitmdump,充当中间人,拦截浏览器到服务器的请求与响应,为Chrome设置好SwitchyOmega谷歌插件的代理地址与端口,让浏览器中请求与响应皆经过中间人mitmdump,最后使用mitmdump对响应进行过滤,筛选出目标接口产生的响应,解析响应体,存储结果到数据库。
整体的操作流程如下
代码的撰写一定要满足mitmproxy的语法。
有的读者可能对SwitchyOmega不太熟悉,虽然上面我放了使用教程,我在这里贴一下SwitchyOmega的配置
先新建一个情景模式,然后填写对应的IP和端口号(Ip就是window的局域网IP,使用ipconfig可以查到,端口号是mitmdump监听的端口号)最后别忘了点击应用选项。
最后这样,将它开启
大家可能在第二步“预览”部分发现Webdriver操作的浏览器就是我平时上网的浏览器,而不是新建了一个用户默认的浏览器,因为我发现douyin会识别用户的浏览器,特别是新建的浏览器特征,每次返回的数据都是一样的,而且只返回一组数据,设置了代理也没用,所以我在webdriver的配置中加入了“–user-data-dir=”参数,这样selenium默认打开的就是我自用的浏览器,通过设置User Data目录,即可轻松的跳过很多网站的登陆验证,而且可以免于复杂的验证码处理流程。这里参考了:
Selenium使用自带浏览器自动化
2022年6月3日14:59:50
import os
import time
import selenium
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from seleniumwire import webdriver
import random
class DouyinSpider(object):
def __init__(self):
super(DouyinSpider, self).__init__()
self.douyinUrl = "https://www.douyin.com/"
self.setWebdriver()
def setWebdriver(self):
option = webdriver.ChromeOptions()
option.add_argument(
'User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53')
# 通过设置User Data目录,即可轻松的跳过很多网站的登陆验证,而可以免于复杂的验证码处理流程。
# 参考:https://blog.csdn.net/a12355556/article/details/112551931
profile_directory = r'--user-data-dir=C:\Users\Administrator\AppData\Local\Google\Chrome\User Data'
option.add_argument(profile_directory)
option.add_experimental_option('excludeSwitches', ['enable-automation'])
# 打开浏览器
driver = webdriver.Chrome(options=option)
self.driver = driver
self.driver.implicitly_wait(5)
def openDouyinPage(self):
"""
打开某音页面,保证主页能够真正打开,为抽取数据做准备
:return:
"""
try:
self.driver.get(self.douyinUrl)
time.sleep(2)
if self.driver.title == "{}音-记录美好生活".format("抖"):
return True
else:
return False
except selenium.common.exceptions.WebDriverException:
self.openDouyinPage()
def start(self):
"""
开始爬取
:return:
"""
os.startfile(os.path.abspath("douyin.bat")) # 开启mitmdump
if not self.openDouyinPage():
self.openDouyinPage()
htmlEle = self.driver.find_element(By.TAG_NAME, "html")
while True:
try:
htmlEle.send_keys(Keys.ARROW_DOWN) # 通过向翻到下一个
self.do_sleep()
except:
pass
def do_sleep(self):
"""
随机睡眠1-2秒
:return:
"""
sleepTime = random.randint(1, 2)
time.sleep(sleepTime)
if __name__ == '__main__':
spider = DouyinSpider()
spider.start()
import mitmproxy.http
import json
import pymongo
import time
def response(flow: mitmproxy.http.HTTPFlow):
aim_url = 'https://www.douyin.com/aweme/v1/web/tab/feed/'
# 捕捉所有目标url开头的url
if flow.request.url.startswith(aim_url):
_json = json.loads(flow.response.text)
aweme_list = _json.get('aweme_list')
for aweme in aweme_list:
item = {}
item['user_name'] = aweme.get("author").get('nickname') # 用户名
item['user_uid'] = aweme.get("author").get('uid') # 个人id
item['user_id'] = aweme.get('author_user_id') # 唯一id
item['share_url'] = aweme.get('share_url')
statistics = aweme.get('statistics')
item['collect_count'] = statistics.get('collect_count')
item['comment_count'] = statistics.get('comment_count')
item['digg_count'] = statistics.get('digg_count')
item['share_count'] = statistics.get('share_count')
item['play_count'] = statistics.get('play_count')
play_addr = aweme.get('video').get('play_addr')
url_list = play_addr.get('url_list')
item['video_nowm_address'] = url_list[0]
for url in url_list:
if "watermark=1" in url:
item['video_nowm_address'] = url
break
item['video_url_list_address'] = url_list
item['data_size'] = play_addr.get("data_size")
item['video_intro'] = aweme.get('desc')
data = dict(item)
data_count = save_to_mongo().count_documents(data)
if data_count == 0:
save_to_mongo().insert_one(data)
print(data)
def save_to_mongo():
# MONGODB 主机名
host = "127.0.0.1"
# MONGODB 端口号
port = 27017
client = pymongo.MongoClient(host=host, port=port)
# 指定数据库
dbname = 'Douyin'
sheetname = 'user_infos'
mydb = client[dbname]
post = mydb[sheetname]
return post
为了偷懒直接写了个bat,主程序也能够自动将其开启。
mitmdump -q -s douYinVideoParse.py -p 8885
本次使用-MitmProxy+Selenium抓取了一些视频数据,通过设置Selenium的webdriver驱动隐藏了爬虫身份,为抓取数据提供了新思路。思路、代码方面有什么不足欢迎各位大佬指正、批评!觉得还行,能点个赞吗?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。