Skip to content

你的第一个自动化

真正的自动化不只是加载一个页面:你要填写表单、点击按钮、等待页面响应,并收集数据。在本页中,你将针对 quotes.toscrape.com(一个专门用于练习抓取的站点)构建一个完整的流程:登录、确认登录成功,并把每一条名言提取为一个类型化对象。

你将学到

像真人一样登录

find() 通过元素的属性定位它们,type_text(humanize=True) 以真实用户的可变节奏打字,其中包括偶尔出现并被修正的拼写错误。你无需先聚焦输入框;Pydoll 会在打字前先点击它。

await tab.go_to('https://quotes.toscrape.com/login')

username = await tab.find(id='username')
await username.type_text('john', humanize=True)

password = await tab.find(id='password')
await password.type_text('SecretPass123', humanize=True)

submit = await tab.find(tag_name='input', type='submit')
await submit.click()

这个站点上的登录表单接受任意用户名和密码,所以这些值只需要看起来真实即可。

确认登录成功

提交后,页面会重新加载并显示一个 Logout 链接。找到那个链接就是你的确认依据。find() 会等待它出现,因此在点击和检查之间不需要 sleep:

logout_link = await tab.find(text='Logout', timeout=5, raise_exc=False)
if logout_link:
    print('Logged in.')
else:
    print('Login failed.')

raise_exc=Falsefind() 在元素始终没有出现时返回 None 而不是抛出异常,从而把控制流保留在你手中。

提取类型化数据

会话激活后,从交互切换到收集。只需一次声明一条名言长什么样,extract_all() 就会返回一组经过校验的对象:

from pydoll.extractor import ExtractionModel, Field


class Quote(ExtractionModel):
    text: str = Field(selector='.text')
    author: str = Field(selector='.author')
    tags: list[str] = Field(selector='.tag')


quotes = await tab.extract_all(Quote, scope='.quote', timeout=5)

for quote in quotes:
    print(f'{quote.author}: {quote.text}')
    print(f'  tags: {", ".join(quote.tags)}')

每个 quote 都是一个真正的 Pydantic 对象:quote.tags 是一个 list[str],你的 IDE 会自动补全字段,quote.model_dump_json() 会将它序列化。无需逐个元素查询,也无需手动类型转换。

完整脚本

创建 first_automation.py

import asyncio

from pydoll.browser.chromium import Chrome
from pydoll.extractor import ExtractionModel, Field


class Quote(ExtractionModel):
    text: str = Field(selector='.text')
    author: str = Field(selector='.author')
    tags: list[str] = Field(selector='.tag')


async def main():
    async with Chrome() as browser:
        tab = await browser.start()

        await tab.go_to('https://quotes.toscrape.com/login')

        username = await tab.find(id='username')
        await username.type_text('john', humanize=True)

        password = await tab.find(id='password')
        await password.type_text('SecretPass123', humanize=True)

        submit = await tab.find(tag_name='input', type='submit')
        await submit.click()

        logout_link = await tab.find(text='Logout', timeout=5, raise_exc=False)
        if not logout_link:
            print('Login failed.')
            return

        quotes = await tab.extract_all(Quote, scope='.quote', timeout=5)
        for quote in quotes:
            print(f'{quote.author}: {quote.text}')

asyncio.run(main())

运行它:

python first_automation.py

你会看到浏览器输入凭据、登录,随后你的终端被作者和名言填满。

下一步