Skip to content

Instantly share code, notes, and snippets.

@charSLee013
Created April 24, 2024 10:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charSLee013/e3feebf457b3650e8c84095789da55d7 to your computer and use it in GitHub Desktop.
Save charSLee013/e3feebf457b3650e8c84095789da55d7 to your computer and use it in GitHub Desktop.
从x-crawl获取的灵感,使用LLM提前HTML里面的想要的内容
# pip install ollama requests
import ollama
import json
import requests
# 将host改为你的ollama的host
client = ollama.Client(host="localhost:11434")
resp = requests.get(url="https://movie.douban.com/top250",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.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
"Cache-Control": "max-age=0",
})
resp.raise_for_status()
if resp.status_code == 200:
html = resp.text
with open("top250.html","w+") as f:
f.write(html)
else:
raise Exception(f"请求失败, 状态码: {resp.status_code}")
# 这里的qwen用的是qwen1_5-32b-chat-q3_k_m.gguf模型
response = client.chat(model='qwen', messages=[
{
'role': 'system',
'content': """你现在是一名爬虫专家和前端专家, coder 用户会将一段 HTML 片段和需要找出的内容一起发送给你, 你需要将该段 HTML 进行解析, 然后分析 coder 用户所提供的信息帮助他找出所需的内容, 并返回如下所说的 JSON 对象格式。
coder 用户: HTML string
我们需要遍历 HTML 片段并检查每个元素的内容, 从而确定哪些项是 coder 所需的。然后, 我们可以根据这些元素在DOM树中的位置来结果。
coder 用户: { message: string }
发来了一个 JavaScript 对象转换为 JSON 字符串的值。
- message:
- 类型: string,
- 作用: 用户的需求。
返回值: { elements: {key: value}[], type: string }
需要返回这样一个 JSON 对象格式。
- elements:
- 类型: array, 里面存放对象 {key: value} key 是属性名, value 是属性值
- 作用: 数组里的每一个对象对应这一个元素的属性。
- type:
- 类型: string, 分别为 "single" | "multiple" | "none"
- 作用: "single" 说明当前 HTML 片段只找到一个目标元素, "multiple" 说明当前 HTML 片段找到多个目标元素, "none" 没有在当前 HTML 片段找到。
你需要根据HTML结构选择合适的属性:
1.解析和理解message
- 解析JSON字符串: 需要解析coder用户发送的JSON字符串,从中提取出message字段。
- 自然语言处理:利用自然语言处理技术对message字段进行分析,以识别出用户希望选择的元素类型(如div、span等)、特征(如类名、ID、属性等),以及其他可能的筛选条件或要求。
- 需求转换:基于自然语言处理的结果,将用户的需求转换为一组可用于查询DOM树的CSS选择器或XPath表达式,一般可以选择BeautifulSoup工具来查询DOM树。
2.解析HTML片段
- HTML解析:AI使用HTML解析器将coder用户提供的HTML片段转换为一个DOM树结构。DOM树是一个树形数据结构,它表示了HTML文档的结构,使得AI能够方便地遍历和查询元素。
- 构建DOM树:解析器将HTML片段中的标签、属性和文本转换为DOM节点,并建立起它们之间的父子关系,形成一个完整的DOM树。
3.选择元素并提取属性
- 元素选择:AI使用在步骤一中生成的CSS选择器或XPath表达式在DOM树中进行元素选择。这将返回一个或多个匹配的元素节点。
- 属性提取:对于每个匹配的元素节点,AI将提取用户指定的属性。这可以通过访问DOM节点的属性集合来完成。AI需要确保提取的属性名称与用户在message字段中指定的相匹配。
- 构建属性对象:对于每个元素的每个属性,AI将创建一个包含key(属性名)和value(属性值)的对象,并将这些对象添加到elements数组中。
4.确定并返回type字段
- 元素计数:AI将统计找到的匹配元素的数量。这个数量将决定返回的type字段的值。
- 设置type字段:
- 如果找到的元素数量为1,type字段设置为"single"。
- 如果找到的元素数量大于1,type字段设置为"multiple"。
- 如果没有找到任何元素,type字段设置为"none"
5.返回结果
- 构建返回对象:将elements数组和type字段组合成一个JSON对象。
"""
},
# {
# 'role': 'user', 'name': 'x-crawl', 'content': html,
# },
{
'role': 'user',
'name':"coder",
'content': f'''
```html
{html}
```
上面是电影列表的HTML, 需要获取电影名(name), 封面链接(picture), 简介(info), 评分(score),
评论人数(commentsNumber)。使用括号的单词作为属性名''',
},
],
keep_alive=1,
options={'seed': 11434, 'temperature': 0.9, 'low_vram': True, 'f16_kv': True},)
r = response['message']['content']
print("抓取的html文件已经保存在本地的top250.html文件中,下面是LLM的回复:\n")
print(r)
抓取的html文件已经保存在本地的top250.html文件中,下面是LLM的回复:
在Python中,我们可以使用BeautifulSoup库来解析HTML并提取所需的信息。以下是一个简单的示例:
```python
from bs4 import BeautifulSoup
import requests
# 获取页面HTML
url = 'https://movie.douban.com/top250'
html = requests.get(url).text
# 解析HTML
soup = BeautifulSoup(html, 'lxml')
# 提取电影列表信息
movies = soup.find_all('div', class_='item')
for movie in movies:
# 电影名
name = movie.find('span', class_='title').text.strip()
# 封面链接
picture = movie.find('img')['src']
# 简介(这里可能需要根据实际HTML结构进行调整,因为简介信息可能位于不同的标签中)
info = movie.find('p', class_='summary').text.strip() if movie.find('p', class_='summary') else ''
# 评分
score = movie.find('span', class_='rating_num').text.strip()
# 评论人数(需要在评分元素的后面查找,因为HTML可能有不同的结构)
commentsNumber = movie.find('span', class_='comments-num') if movie.find('span', class_='comments-num') else ''
print(name, picture, info, score, commentsNumber)
```
这段代码会获取电影列表页面的HTML,并使用BeautifulSoup库来解析这个HTML。然后,它会遍历每一个“电影项目”,提取出所需的信息。
注意,一些信息(如电影简介)可能位于不同的HTML标签中,这取决于实际的HTML结构。在实际应用中,你可能需要根据HTML的实际情况进行调整。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment