mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
修改ChromiumFrame,未完成;str_to_loc()修改tx=xxxx的语法,用text()替代.
This commit is contained in:
parent
6fedd57677
commit
51cb918b32
@ -1251,7 +1251,7 @@ def run_script(page_or_ele, script, as_expr=False, timeout=None, args=None, not_
|
||||
:param script: js文本
|
||||
:param as_expr: 是否作为表达式运行,为True时args无效
|
||||
:param timeout: 超时时间
|
||||
:param args: 参数,按顺序在js文本中对应argument[0]、argument[2]...
|
||||
:param args: 参数,按顺序在js文本中对应argument[0]、argument[1]...
|
||||
:param not_change: 执行时是否切换页面对象模式
|
||||
:return: js执行结果
|
||||
"""
|
||||
|
@ -13,6 +13,7 @@ from .chromium_element import ChromiumElement
|
||||
class ChromiumFrame(ChromiumBase):
|
||||
def __init__(self, page, ele):
|
||||
self.page = page
|
||||
self.address = self.page.address
|
||||
node = page.run_cdp('DOM.describeNode', nodeId=ele.node_id, not_change=True)['node']
|
||||
self.frame_id = node['frameId']
|
||||
self._backend_id = ele.backend_id
|
||||
@ -42,20 +43,23 @@ class ChromiumFrame(ChromiumBase):
|
||||
attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs]
|
||||
return f'<ChromiumFrame {self.frame_ele.tag} {" ".join(attrs)}>'
|
||||
|
||||
# def _reload_document(self):
|
||||
# self._frame_ele = ChromiumElement(self.page, backend_id=self._backend_id)
|
||||
# node = self.page.run_cdp('DOM.describeNode', nodeId=self._frame_ele.node_id, not_change=True)['node']
|
||||
#
|
||||
# if self._is_inner_frame():
|
||||
# self._is_diff_domain = False
|
||||
# self.doc_ele = ChromiumElement(self.page, backend_id=node['contentDocument']['backendNodeId'])
|
||||
# super().__init__(self.page.address, self.page.tab_id, self.page.timeout)
|
||||
# else:
|
||||
# self._is_diff_domain = True
|
||||
# self._tab_obj.stop()
|
||||
# super().__init__(self.page.address, self.frame_id, self.page.timeout)
|
||||
# obj_id = super().run_script('document;', as_expr=True)['objectId']
|
||||
# self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
||||
def _reload(self):
|
||||
self._frame_ele = ChromiumElement(self.page, backend_id=self._backend_id)
|
||||
node = self.page.run_cdp('DOM.describeNode', nodeId=self._frame_ele.node_id, not_change=True)['node']
|
||||
|
||||
if self._is_inner_frame():
|
||||
print('-111')
|
||||
self._is_diff_domain = False
|
||||
self.doc_ele = ChromiumElement(self.page, backend_id=node['contentDocument']['backendNodeId'])
|
||||
super().__init__(self.address, self.page.tab_id, self.page.timeout)
|
||||
print('+111')
|
||||
else:
|
||||
print('-222')
|
||||
self._is_diff_domain = True
|
||||
super().__init__(self.address, self.frame_id, self.page.timeout)
|
||||
obj_id = super().run_script('document;', as_expr=True)['objectId']
|
||||
self.doc_ele = ChromiumElement(self, obj_id=obj_id)
|
||||
print('+222')
|
||||
|
||||
def _get_new_document(self):
|
||||
"""刷新cdp使用的document数据"""
|
||||
@ -156,7 +160,11 @@ class ChromiumFrame(ChromiumBase):
|
||||
@property
|
||||
def title(self):
|
||||
"""返回页面title"""
|
||||
return self.ele('t:title').text
|
||||
while True:
|
||||
try:
|
||||
return self.ele('t:title').text
|
||||
except:
|
||||
self._reload()
|
||||
|
||||
@property
|
||||
def cookies(self):
|
||||
@ -251,7 +259,7 @@ class ChromiumFrame(ChromiumBase):
|
||||
"""运行javascript代码 \n
|
||||
:param script: js文本
|
||||
:param as_expr: 是否作为表达式运行,为True时args无效
|
||||
:param args: 参数,按顺序在js文本中对应argument[0]、argument[2]...
|
||||
:param args: 参数,按顺序在js文本中对应argument[0]、argument[1]...
|
||||
:return: 运行的结果
|
||||
"""
|
||||
return self.doc_ele.run_script(script, as_expr=as_expr, *args)
|
||||
|
@ -28,6 +28,8 @@ class ChromiumFrame(ChromiumBase):
|
||||
|
||||
def __repr__(self) -> str: ...
|
||||
|
||||
def _reload(self) -> None: ...
|
||||
|
||||
def _get_new_document(self) -> None: ...
|
||||
|
||||
def _onFrameAttached(self, **kwargs): ...
|
||||
|
@ -113,8 +113,8 @@ def get_loc(loc: Union[tuple, str], translate_css: bool = False) -> tuple:
|
||||
|
||||
|
||||
def str_to_loc(loc: str) -> tuple:
|
||||
"""处理元素查找语句 \n
|
||||
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n
|
||||
"""处理元素查找语句 \n
|
||||
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n
|
||||
"""
|
||||
loc_by = 'xpath'
|
||||
@ -159,7 +159,7 @@ def str_to_loc(loc: str) -> tuple:
|
||||
|
||||
# 根据文本查找
|
||||
elif loc.startswith('text='):
|
||||
loc_str = f'//*[.={_make_search_str(loc[5:])}]'
|
||||
loc_str = f'//*[text()={_make_search_str(loc[5:])}]'
|
||||
elif loc.startswith('text:') and loc != 'text:':
|
||||
loc_str = f'//*/text()[contains(., {_make_search_str(loc[5:])})]/..'
|
||||
|
||||
|
@ -164,4 +164,79 @@ page.to_tab('0B300BEA6F1F1F4D5DE406872B79B1AD')
|
||||
|
||||
## 📍 获取标签页对象
|
||||
|
||||
# 未完待续
|
||||
可以用`WebPage`或`ChromiumPage`的`get_tab()`方法获取标签页对象,然后可以使用这个对象对标签页进行操作。
|
||||
|
||||
`get_tab()`
|
||||
|
||||
**参数:**
|
||||
|
||||
- `tab_id`:要获取的标签页 id,为`None`时获取当前标签页
|
||||
|
||||
**返回:**`ChromiumTab`对象
|
||||
|
||||
```python
|
||||
tab = page.get_tab() # 获取当前标签页对象
|
||||
```
|
||||
|
||||
## 📍 使用标签页对象
|
||||
|
||||
每个`ChromiumTab`对象控制一个浏览器标签页,方法和直接使用`ChromiumPage`一致,只比`ChromiumPage`少了控制标签页功能。
|
||||
|
||||
```python
|
||||
tab.get('https://www.baidu.com') # 使用标签页对象
|
||||
```
|
||||
|
||||
## 📍 同时控制多标签页示例
|
||||
|
||||
下面的例子演示多个线程控制多个标签页进行内容采集。
|
||||
|
||||
```python
|
||||
from threading import Thread
|
||||
|
||||
from DrissionPage import ChromiumPage
|
||||
|
||||
|
||||
def 采集(tab):
|
||||
# 采集 4 页
|
||||
for _ in range(4):
|
||||
# 获取某页所有库名称并打印
|
||||
for i in tab.eles('.title project-namespace-path'):
|
||||
print(i.text)
|
||||
|
||||
# 点击翻页
|
||||
tab('@rel=next').click()
|
||||
# 等待页面进入加载
|
||||
tab.wait_loading()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 新建页面对象
|
||||
page = ChromiumPage()
|
||||
# 第一个标签页访问网址
|
||||
page.get('https://gitee.com/explore/ai')
|
||||
# 获取第一个标签页对象
|
||||
tab1 = page.get_tab()
|
||||
# 新建一个标签页并访问另一个网址
|
||||
page.new_tab('https://gitee.com/explore/machine-learning')
|
||||
# 获取第二个标签页对象
|
||||
tab2 = page.get_tab()
|
||||
|
||||
# 多线程同时处理多个页面
|
||||
Thread(target=采集, args=(tab1,)).start()
|
||||
Thread(target=采集, args=(tab2,)).start()
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```console
|
||||
MindSpore/mindspore
|
||||
PaddlePaddle/Paddle
|
||||
MindSpore/docs
|
||||
scruel/Notes-ML-AndrewNg
|
||||
MindSpore/graphengine
|
||||
inspur-inna/inna1.0
|
||||
MindSpore/course
|
||||
MindSpore/community
|
||||
|
||||
后面省略。。。
|
||||
```
|
||||
|
258
docs/WebPage使用方法/3.9iframe操作.md
Normal file
258
docs/WebPage使用方法/3.9iframe操作.md
Normal file
@ -0,0 +1,258 @@
|
||||
`<iframe>`元素是一种特殊的元素,它既是元素,也是页面,因此独立一个章节对其进行介绍。
|
||||
|
||||
与 selenium 不同,DrissionPage 无需切入切出即可处理`<iframe>`元素。因此可实现跨级元素查找、元素内部单独跳转、同时操作`<iframe>`内外元素、多线程控制多个`<iframe>`等操作,功能更灵活,逻辑更清晰。
|
||||
|
||||
我们使用菜鸟教程在线编辑器来演示:
|
||||
|
||||
[菜鸟教程在线编辑器 (runoob.com)](https://www.runoob.com/try/try.php?filename=tryhtml_iframe)
|
||||
|
||||
源代码框内容要作一点调整,然后按“点击运行”:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>菜鸟教程(runoob.com)</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe id="sss" src="https://www.runoob.com">
|
||||
<p>您的浏览器不支持 iframe 标签。</p>
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
按`F12`,可以看到网页右侧是一个两层`<iframe>`,一个 id 是`'iframeResult'`的`<iframe>`里面有一个 id 是`'sss'`的`<iframe>`。最里层的`<iframe>`页面指向 https://www.runoob.com。
|
||||
|
||||
# ✔ 获取`<iframe>`对象
|
||||
|
||||
现在我们获取最里层`<iframe>`对象。方法和直接获取元素一样:
|
||||
|
||||
```python
|
||||
iframe = page('#sss')
|
||||
print(iframe.html)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```console
|
||||
<iframe id="sss" src="https://www.runoob.com"><html><head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>菜鸟教程 - 学的不仅是技术,更是梦想!</title>
|
||||
|
||||
<meta name="robots" content="max-image-preview:large">
|
||||
|
||||
下面省略。。。
|
||||
```
|
||||
|
||||
这个`ChromiumFrame`对象既是页面也是元素,下面演示其功能。
|
||||
|
||||
# ✔ 查找`<iframe>`内元素
|
||||
|
||||
从刚才获取元素对象看出,我们并不须要先切入 id 为`'iframeResult'`的`<iframe>`,就可以获取到里面的元素。所以我们获取元素也并不一定要先获取到`ChromiumFrame`对象。
|
||||
|
||||
## 📍 在`<iframe>`内查找
|
||||
|
||||
使用我们刚才获取到的元素,可以在里面查找元素:
|
||||
|
||||
```python
|
||||
ele = iframe('首页')
|
||||
print(ele)
|
||||
|
||||
# 输出:<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
```
|
||||
|
||||
## 📍 页面跨`<iframe>`查找
|
||||
|
||||
如果`<iframe>`元素的网址和主页面是同域的,我们可以直接用页面对象查找`<iframe>`内部元素,而无需先获取`ChromiumFrame`对象:
|
||||
|
||||
```python
|
||||
ele = page('首页')
|
||||
print(ele)
|
||||
|
||||
# 输出:<ChromiumElement a href='https://www.runoob.com/' data-id='index' title='菜鸟教程' class='current'>
|
||||
```
|
||||
|
||||
只要是同域名的,无论跨多少曾`<iframe>`都能用页面对象直接获取。
|
||||
|
||||
## 📍 与 selenium 对比
|
||||
|
||||
`WebPage`:
|
||||
|
||||
```python
|
||||
from DrissionPage import WebPage
|
||||
|
||||
page = WebPage()
|
||||
ele = page('首页')
|
||||
```
|
||||
|
||||
`MixPage`(基于 selenium):
|
||||
|
||||
```python
|
||||
from DrissionPage import MixPage
|
||||
|
||||
page = MixPage()
|
||||
page.to_frame('#iframeResult')
|
||||
page.to_frame('#sss')
|
||||
ele = page('首页')
|
||||
page.to_frame.main()
|
||||
```
|
||||
|
||||
可见,原来的逻辑要切入切出,比较繁琐。
|
||||
|
||||
# ✔ `ChromiumFrame`的元素特征
|
||||
|
||||
正如上面所说,`ChromiumFrame`既是元素也是页面,这里说一下其元素方面的用法。
|
||||
|
||||
## 📍 `tab_id`
|
||||
|
||||
此属性返回`<iframe>`元素所在标签页的 id。
|
||||
|
||||
## 📍 `tag`
|
||||
|
||||
此属性返回元素名称。
|
||||
|
||||
## 📍 `html`
|
||||
|
||||
此属性返回整个`<iframe>`元素的 outerHTML 文本。
|
||||
|
||||
## 📍 `inner_html`
|
||||
|
||||
此属性返回 innerHTML 文本。
|
||||
|
||||
## 📍 `attrs`
|
||||
|
||||
此属性以`dict`形式返回元素所有 attribute 属性。
|
||||
|
||||
## 📍 `size`
|
||||
|
||||
此属性以`tuple`形式返回元素大小。
|
||||
|
||||
## 📍 `location`
|
||||
|
||||
此属性以`tuple`形式返回元素在主页面中的位置。
|
||||
|
||||
## 📍 `is_displayed`
|
||||
|
||||
此属性返回元素是否可见。
|
||||
|
||||
## 📍 `xpath`
|
||||
|
||||
此属性返回元素在其页面上的 xpath 路径。
|
||||
|
||||
## 📍 `css_path`
|
||||
|
||||
此属性返回元素在其页面上的 css selector 路径。
|
||||
|
||||
## 📍 `attr()`
|
||||
|
||||
此方法用于一个获取元素 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
|
||||
**返回:** 属性值文本,没有该属性返回`None`
|
||||
|
||||
## 📍 `set_attr()`
|
||||
|
||||
此方法用于设置元素的 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 `remove_attr()`
|
||||
|
||||
此方法用于删除元素的 attribute 属性。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `attr`:属性名
|
||||
|
||||
**返回:**`None`
|
||||
|
||||
## 📍 相对定位
|
||||
|
||||
相对定位方法与普通元素一致,详见获取元素章节。
|
||||
|
||||
- `parent()`:返回上面某一级父元素。
|
||||
|
||||
- `prev()`:返回前面的一个兄弟元素。
|
||||
|
||||
- `next()`:返回后面的一个兄弟元素。
|
||||
|
||||
- `before()`:返回当前元素前面的一个元素。
|
||||
|
||||
- `after()`:返回当前元素后面的一个元素。
|
||||
|
||||
- `prevs()`:返回前面全部兄弟元素或节点组成的列表。
|
||||
|
||||
- `nexts()`:返回后面全部兄弟元素或节点组成的列表。
|
||||
|
||||
- `befores()`:返回当前元素后面符合条件的全部兄弟元素或节点组成的列表。
|
||||
|
||||
# ✔ `ChromiumFrame`的页面特征
|
||||
|
||||
## 📍 `url`
|
||||
|
||||
此属性返回页面当前 url。
|
||||
|
||||
## 📍 `title`
|
||||
|
||||
此属性返回页面当前 title 文本。
|
||||
|
||||
## 📍 `cookies`
|
||||
|
||||
此属性返回页面当前 cookies 内容。
|
||||
|
||||
## 📍 `get()`
|
||||
|
||||
此方法用于实现`<iframe>`页面跳转。
|
||||
|
||||
```python
|
||||
iframe.get('https://www.runoob.com/css3/css3-tutorial.html')
|
||||
```
|
||||
|
||||
## 📍 `refresh()`
|
||||
|
||||
此方法用于刷新页面。
|
||||
|
||||
```python
|
||||
iframe.refresh()
|
||||
```
|
||||
|
||||
## 📍 `ready_state`
|
||||
|
||||
此属性为页面加载状态。
|
||||
|
||||
## 📍 `is_loading`
|
||||
|
||||
此属性返回页面是否正在加载。
|
||||
|
||||
## 📍 `active_ele`
|
||||
|
||||
此属性返回页面中焦点所在元素。
|
||||
|
||||
## 📍 `frame_size`
|
||||
|
||||
此属性以`tuple`形式返回页面大小。
|
||||
|
||||
## 📍 `run_script()`
|
||||
|
||||
此方法用于在`<iframe>`内执行 js 脚本。
|
||||
|
||||
**参数:**
|
||||
|
||||
- `script`:js文本
|
||||
|
||||
- `as_expr`:是否作为表达式运行,为`True`时`args`无效
|
||||
|
||||
- `*args`:参数,按顺序在 js 文本中对应 argument[0]、argument[1]...
|
||||
|
||||
**返回:** 运行的结果
|
@ -21,6 +21,7 @@
|
||||
* [🔨 3.6 获取网页信息](WebPage使用方法\3.6获取网页信息.md)
|
||||
* [🔨 3.7 页面操作](WebPage使用方法\3.7页面操作.md)
|
||||
* [🔨 3.8 标签页操作](WebPage使用方法\3.8标签页操作.md)
|
||||
* [🔨 3.9 iframe操作](WebPage使用方法\3.9iframe操作.md)
|
||||
|
||||
* [🛠 4 MixPage 使用方法](#)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user