【问题标题】:How do I find and store dynamically loaded elements with python selenium?如何使用 python selenium 查找和存储动态加载的元素?
【发布时间】:2021-10-29 19:45:46
【问题描述】:

我正在尝试使用 Python Selenium 从this 个人资料上的“关注者”按钮列表中抓取用户名。我不能这样做有两个原因:

  1. 我无法使用driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") 滚动列表,因为列表有2 个滚动条(我不知道为什么它有2 个)。如果我尝试滚动,它会滚动个人资料页面,而不是实际列表。
  2. 即使我设法滚动列表,我应该如何存储用户名?用户是动态加载的,由于某种原因,类 id 看起来像这样class='st--c-PJLV st--c-dhzjXW st--c-edagZx'

我已经尝试了几种方法来解决这个问题,但我无法达到我想要的结果,感谢任何帮助。以下是我尝试使用的一些代码 sn-ps,但出现错误:

scrollElem = driver.find_elements(By.XPATH, "//div[@class='st--c-PJLV st--c-dhzjXW st--c- 
edagZx']/a")
followernumber = 2000
scrollElem[len(scrollElem)-1].location_once_scrolled_into_view
for i in range(0,followernumber):
    new = len(scrollElem)+i
    newname = driver.find_element(By.XPATH, "(//div[@class='st--c-PJLV st--c-dhzjXWstedagZx']/a)[%i]"%new)
    print(newname.text, i)
    newname.location_once_scrolled_into_view
    time.sleep(1)

得到错误:selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"(//div[@class='st--c-PJLV st--c-dhzjXW st--c-edagZx']/a)[47]"}

我还尝试使用此算法在列表底部滚动并在加载时存储元素,但这也不起作用:

def scrollDown():
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(SCROLL_PAUSE_TIME)
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

算法滚动了个人资料页面,而不是关注者列表

如果我是网络抓取的新手,我将不胜感激!

【问题讨论】:

    标签: python selenium web-scraping


    【解决方案1】:

    尝试使用 requests 模块获取该个人资料的所有关注者姓名:

    import requests
    
    link = 'https://hasura2.foundation.app/v1/graphql'
    payload = {"query":"query userFollowersQuery($publicKey: String!, $currentUserPublicKey: String!, $offset: Int!, $limit: Int!) {\n  follows: follow(\n    where: {followedUser: {_eq: $publicKey}, isFollowing: {_eq: true}}\n    offset: $offset\n    limit: $limit\n  ) {\n    id\n    user: userByFollowingUser {\n      name\n      username\n      profileImageUrl\n      userIndex\n      publicKey\n      follows(where: {user: {_eq: $currentUserPublicKey}, isFollowing: {_eq: true}}) {\n        createdAt\n        isFollowing\n      }\n    }\n  }\n}\n","variables":{"currentUserPublicKey":"","publicKey":"0xF74d1224931AFa9cf12D06092c1eb1818D1E255C","offset":0,"limit":48},"operationName":"userFollowersQuery"}
    
    with requests.Session() as s:
        s.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36'
        
        while True:
            resp = s.post(link,json=payload)
            if not resp.json()['data']['follows']:break
            for item in resp.json()['data']['follows']:
                print(item['user']['username'])
    
            payload['variables']['offset']+=48
    

    【讨论】:

    • 你太棒了!非常感谢,这很好用!不知道哈苏拉!你能带我看更多关于它和使用请求进行网络抓取的文章吗?再次感谢您!
    • 顺便问一下你是怎么知道这个网站使用了hasura的?
    • 导航到您帖子中的网址,使用F12 打开 chrome 开发工具,找到并按Network 标签,然后按All 标签。现在,重新加载页面。您应该在其左侧窗格中看到不同类型的 url。当您单击任何 URL 时,您将在其右窗格中看到所有详细信息。这是我找到答案中使用的网址的地方。
    • 你知道我使用请求从配置文件中获取公钥吗?
    猜你喜欢
    • 1970-01-01
    • 2020-05-18
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多