鱼C论坛

 找回密码
 立即注册
查看: 1600|回复: 12

[已解决]爬虫挑战

[复制链接]
发表于 2023-11-27 22:45:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
请教一下,

最近通过docker拉取了小雅的资源库,

地址是:  http://www.038909.xyz:5678/

如何爬取整个网站的资源。不下载,只获取文件目录,拼接成如下的
http://www.038909.xyz:5678/d/%E6%B8%B8%E6%88%8F/PC/03.%E7%A7%8D%E5%AD%90%E6%96%87%E4%BB%B6%E9%9B%86%E5%90%88/%E7%A7%8D%E5%AD%90%E6%96%87%E4%BB%B6/2012%E5%B9%B46%E6%9C%88~11%E6%9C%88/%E5%90%88%E9%9B%86.exe




ps自己的网站,随便折腾。

好像是通过post实现【http://www.038909.xyz:5678/api/fs/list】

但不太好获取   {path: "/有声书", password: "", page: 1, per_page: 30, refresh: false}

有想试试的吗?
最佳答案
2023-11-28 01:56:38
简单的看了一下,挺简单的,^_^
简单的说一下思路
先把主页面爬下来,看了看发现没有这个目录列表
看了下浏览器接收到的数据,发现了你提到的这个地址
http://www.038909.xyz:5678/api/fs/list

简单的研究了一下,得到了这个地址的使用方法
其实就是多看几个目录在这个地址上收到的数据,找规律么
然后就是根据找到的规律写代码了

另外,这个网站的反爬机制还不错
我目前最简单的解决方法也就是sleep一会了
1秒一个目录,出错了再10秒重试一下
如果这是你自己的网站,在测试爬虫的时候可以把这个目录弄的小一点么
我这爬了十几分钟了,才爬到 /体育/健身 这个目录,^_^
下面这个程序用于获取这个网站的整个目录树
#!/usr/bin/env python
#coding=utf-8

import requests
import json
import itertools
import time
from retry import retry
import sys
import logging

logging.basicConfig(stream = sys.stderr, level = logging.WARNING)
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}

@retry(delay = 10, logger = logging.getLogger())
def list_dir(path):
    time.sleep(1)
    print(path, file = sys.stderr)
    content = []
    for page in itertools.count(1):
        json_ = {"path": path, "password": "", "page": page, "per_page": 30, "refresh": False}
        url = 'http://www.038909.xyz:5678/api/fs/list'
        response = requests.post(url, json = json_, headers = headers)
        response.encoding = 'utf-8'
        json_ = json.loads(response.text)
        data = json_['data']
        if data['content'] != None: content.extend(data['content'])
        total = data['total']
        if total == len(content): break
    for i in content:
        if not i['is_dir']: continue
        i['dir_content'] = list_dir(path + i['name'] + '/')
    return content

content = list_dir('/')
print(content)

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-27 22:45:35 | 显示全部楼层
可以使用Python的requests库来发送POST请求获取文件目录信息,并对返回的数据进行解析。以下是一个示例代码:
import requestsdef get_file_list(url, path):    data = {        "path": path,        "password": "",        "page": 1,        "per_page": 30,        "refresh": False    }        response = requests.post(url, json=data)    if response.status_code == 200:        files = response.json().get("files")        if isinstance(files, list):            return files    return []def generate_download_url(base_url, file_path):    # 将文件路径中的特殊字符编码转换为URL编码    encoded_path = "/".join([requests.utils.quote(part) for part in file_path.split("/")])    return f"{base_url}/{encoded_path}"url = "http://www.038909.xyz:5678/api/fs/list"base_url = "http://www.038909.xyz:5678"file_list = get_file_list(url, "/")for file_info in file_list:    file_path = file_info.get("path")    download_url = generate_download_url(base_url, file_path)    print(download_url)
这段代码先定义了一个`get_file_list`函数,用于发送POST请求获取文件目录信息。然后定义了一个`generate_download_url`函数,用于根据文件路径生成可下载的文件URL。最后在主程序部分,通过调用`get_file_list`函数获取文件列表,并循环遍历输出每个文件的下载URL。

请注意,这段代码仅提供了实现思路和示例代码,具体情况可能需要根据网站的实际接口和返回数据格式进行调整。同时,爬取网站资源可能涉及到合法性和道德性问题,请务必遵守相关法律法规和网站的使用规定。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-27 22:47:09 | 显示全部楼层
乱码了,路径如下。
1111.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-27 22:47:36 | 显示全部楼层
fineconey 发表于 2023-11-27 22:47
乱码了,路径如下。

如果路径中包含了URL编码的特殊字符,可以使用Python的urllib库来进行URL解码。以下是更新过后的代码示例:import requestsfrom urllib.parse import unquotedef get_file_list(url, path):    data = {        "path": path,        "password": "",        "page": 1,        "per_page": 30,        "refresh": False    }    response = requests.post(url, json=data)    if response.status_code == 200:        files = response.json().get("files")        if isinstance(files, list):            return files    return []def generate_download_url(base_url, file_path):    # 解码URL编码的文件路径    decoded_path = unquote(file_path)    return f"{base_url}/{decoded_path}"url = "http://www.038909.xyz:5678/api/fs/list"base_url = "http://www.038909.xyz:5678"direc_path = "/%E6%B8%B8%E6%88%8F/PC/03.%E7%A7%8D%E5%AD%90%E6%96%87%E4%BB%B6%E9%9B%86%E5%90%88/%E7%A7%8D%E5%AD%90%E6%96%87%E4%BB%B6/2012%E5%B9%B46%E6%9C%88~11%E6%9C%88/%E5%90%88%E9%9B%86.exepsfile_list = get_file_list(url, direc_path)for file_info in file_list:    file_path = file_info.get("path")    download_url = generate_download_url(base_url, file_path)    print(download_url)这段代码在之前的基础上,增加了一个`unquote`函数的调用来解码URL编码的文件路径。由于你提供的示例路径是已经进行了URL编码的,所以需要将路径进行解码才能得到正确的下载URL。请注意,这代码仅提供了解决乱码问题的思路和示例代码,请根据实际情况进行调整。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-27 22:56:27 | 显示全部楼层
明天有空的话看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-28 01:56:38 | 显示全部楼层    本楼为最佳答案   
简单的看了一下,挺简单的,^_^
简单的说一下思路
先把主页面爬下来,看了看发现没有这个目录列表
看了下浏览器接收到的数据,发现了你提到的这个地址
http://www.038909.xyz:5678/api/fs/list

简单的研究了一下,得到了这个地址的使用方法
其实就是多看几个目录在这个地址上收到的数据,找规律么
然后就是根据找到的规律写代码了

另外,这个网站的反爬机制还不错
我目前最简单的解决方法也就是sleep一会了
1秒一个目录,出错了再10秒重试一下
如果这是你自己的网站,在测试爬虫的时候可以把这个目录弄的小一点么
我这爬了十几分钟了,才爬到 /体育/健身 这个目录,^_^
下面这个程序用于获取这个网站的整个目录树
#!/usr/bin/env python
#coding=utf-8

import requests
import json
import itertools
import time
from retry import retry
import sys
import logging

logging.basicConfig(stream = sys.stderr, level = logging.WARNING)
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"}

@retry(delay = 10, logger = logging.getLogger())
def list_dir(path):
    time.sleep(1)
    print(path, file = sys.stderr)
    content = []
    for page in itertools.count(1):
        json_ = {"path": path, "password": "", "page": page, "per_page": 30, "refresh": False}
        url = 'http://www.038909.xyz:5678/api/fs/list'
        response = requests.post(url, json = json_, headers = headers)
        response.encoding = 'utf-8'
        json_ = json.loads(response.text)
        data = json_['data']
        if data['content'] != None: content.extend(data['content'])
        total = data['total']
        if total == len(content): break
    for i in content:
        if not i['is_dir']: continue
        i['dir_content'] = list_dir(path + i['name'] + '/')
    return content

content = list_dir('/')
print(content)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-28 02:03:23 | 显示全部楼层
fineconey 发表于 2023-11-27 22:47
乱码了,路径如下。

还是直接用 api 吧,这样去拼 url 不得行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-11-28 19:58:25 | 显示全部楼层
再改一改,我发现文件没有爬到下载地址,需要使用下面这个地址再对文件进行一次请求
http://www.038909.xyz:5678/api/fs/get

爬了两个多小时才爬到 "/体育/健身/【赛普健身专业视频】价值19800元/实用工具图表/体质判断对照图",^_^
然后服务器断开连接了,看起来是我的ip被封了,^_^
#!/usr/bin/env python
#coding=utf-8

import requests
import json
import itertools
import time
from retry import retry
import sys
import logging

logging.basicConfig(stream = sys.stderr, level = logging.WARNING)
headers = {"User-Agent": "Mozilla/6.0 (X11; Linux x86_64; rv:109.0) Gecko/20120101 Firefox/139.0"}
dir_url = 'http://www.038909.xyz:5678/api/fs/list'
file_url = 'http://www.038909.xyz:5678/api/fs/get'

@retry(delay = 5, logger = logging.getLogger())
def read_json(path, url, json_):
    time.sleep(1)
    response = requests.post(url, json = json_, headers = headers)
    json_ = json.loads(response.text)
    if json_['code'] != 200: raise ValueError(json_['message'])
    return json_['data']

def read_file(path):
    print(path, file = sys.stderr)
    json_ = {"path": path, "password": ""}
    return read_json(path, file_url, json_)

def read_dir(path):
    print(path, file = sys.stderr)
    content = []
    for page in itertools.count(1):
        json_ = {"path": path, "password": "", "page": page, "per_page": 30, "refresh": False}
        data = read_json(path, dir_url, json_)
        if data['content'] != None: content.extend(data['content'])
        total = data['total']
        if total == len(content): break
    for i in range(len(content)):
        is_dir = content[i]['is_dir']
        name = content[i]['name']
        if is_dir: content[i]['dir_content'] = read_dir(path + name + '/')
        else: content[i] = read_file(path + name)
    return content

#content = read_dir('/游戏/PC/07.运行库/')
content = read_dir('/')
print(content)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-28 20:19:37 | 显示全部楼层
人造人 发表于 2023-11-28 19:58
再改一改,我发现文件没有爬到下载地址,需要使用下面这个地址再对文件进行一次请求

我临时关了,看了下后台,走了接近n多流量。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-11-28 20:20:27 | 显示全部楼层
人造人 发表于 2023-11-28 19:58
再改一改,我发现文件没有爬到下载地址,需要使用下面这个地址再对文件进行一次请求

结构是一样的,可以试试这个。

https://pan.mediy.cn/
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-28 21:03:18 | 显示全部楼层
fineconey 发表于 2023-11-28 20:20
结构是一样的,可以试试这个。

https://pan.mediy.cn/

需要我继续挂这个脚本去爬整个目录树吗?
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-11-28 21:57:39 | 显示全部楼层
人造人 发表于 2023-11-28 21:03
需要我继续挂这个脚本去爬整个目录树吗?
^_^

喜欢什么就下载什么吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-12-1 16:04:24 | 显示全部楼层
人造人 发表于 2023-11-28 01:56
简单的看了一下,挺简单的,^_^
简单的说一下思路
先把主页面爬下来,看了看发现没有这个目录列表

可惜了,对于我们这样的新手来说,你的很多库都不知道是干嘛的,哈哈!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 22:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表