1

我是网络抓取的新手,所以我正在研究一堆不同的方法。其中之一(我最兴奋的一个)是使用 Python 库“requests-html”,它支持 Javascript 内容的呈现。

基本上我想知道如何单击“下一步”按钮进入给定页面以获取更多 JS 呈现的内容。使用示例网页“ https://us-proxy.org/ ”。我可以很容易地获得“下一步”按钮的 xpath,但我不知道如何启动它。

我对“requests-html”的理解是,它基本上是通过控制一个无头 chromium 实例并使用它来使用 Javascript 呈现页面来工作的。到目前为止一切都很好,到目前为止我已经对它进行了一些试验并且效果很好,但是文档中提到它包含分页功能。坦率地说,我似乎无法让它工作,除了说它在那里之外,创作者的文档并没有详细说明。

如果有人可以解释人们如何使用这个库来实现这一点,或者即使他们可以向我指出一些更充实的文档(如果有任何在线文档),我会很高兴。我花了一些时间四处寻找是否可以找到任何东西,但是考虑到它看起来有多么强大,我能够找到的关于“requests-html”的内容却很少。我也检查了 ReadTheDocs,它基本上没有任何信息。我想我可以走出去,稍微解决一下问题并深入研究pyppeteer,但这似乎可能是另一个兔子洞......

---------------------------- 我的示例脚本 ------------------- ---

targetURL = "https://us-proxy.org/"

print("script running")

# create an HTML Session Object
session = HTMLSession()

# Use the object to needed webpage
responseObject =  session.get(targetURL)
responseObject.html.next()

option_tagsNoRender = responseObject.html.xpath("//td")
print("\n\nNo Rend: ", len(option_tagsNoRender) )
print("\n\n", option_tagsNoRender[0].full_text)


# Run Javascript Code on target webpage
responseObject.html.render(sleep=10)


option_tags = responseObject.html.xpath("//td")
print("\n\nPost Render: ", len(option_tags) )
#print(dir(option_tags[0]))

print("\n\n", option_tags[0].full_text)

for tag in option_tags:
    #pass
    print(tag.full_text)

- - - - - - - - 结尾 - - - - - - - - - - - - - - - - - ---------

由于创建者文档实际上确实提到了“.next()”方法,因此我尝试执行它(如示例脚本中所示)。根据输出,它似乎没有做任何事情(尽管我不知道我是否正确实现了它)。无论我注释掉该行还是保留它,标记搜索的结果都是相同的。它似乎没有推进 JS 呈现的页面。

感谢任何指导或见解。谢谢!

更新:

好的,所以我仔细查看了文档,他们确实提到如果您在渲染调用期间使用“keep_page”选项,您可以与页面交互。这使我找到了 pyppeteers 文档(当然在 requests-html 中使用)的发现路径,这似乎揭示了一个非常简单的 '.click()' 方法,似乎并没有阻塞下一个的 xpath 选择器我喂它的按钮。不幸的是,我仍然没有看到任何证据表明它成功单击了链接,并且我不断收到一条错误消息,提示“RuntimeWarning: coroutine 'clickNext' is never awaited”。

这是我编写的用于单击下一个按钮的简单函数,该按钮现在给我该消息:

-------------------------------------------------- -----

async def clickNext():

await asyncio.wait([ responseObject.html.page.click('//a[@aria-controls][@data-dt-idx="9"]'), 
                     responseObject.html.page.waitFor(5000),])

-------------------------------------------------- -----

到目前为止,我在异步编程和协程方面的经验为零,所以他的意思是我正在深入研究这一点,但如果有人对我在这方面做错了什么有任何见解,我会很感激你愿意分享的任何信息。谢谢!

4

1 回答 1

0

所以你实际上不需要渲染 JS 来获取所有 10 个页面。在最初的请求中,所有 10 页都作为一个大表提供,然后分页发生。因此,使用 requests_html 和 pandas 您可以像这样获取所有数据:

from requests_html import AsynchHTMLSession
import pandas as pd

s = AsyncHTMLSession()
async def main():
    r = await s.get('https://us-proxy.org/')     
    table = r.html.find('table', first=True)   
    headers = [i.text for i in table.find('th') if i.text]
    rows = table.find('tr')
    data = []
    for row in rows:
        row = [i.text for i in row.find('td')]
        if row:
            data.append(row)            
    return pd.DataFrame(data, columns=headers)

df = s.run(main)[0]
print(df)

          IP Address   Port Code  ... Google Https            Last Checked
0     208.180.237.55  31012   US  ...     no    no           3 seconds ago
1      173.46.67.172  58517   US  ...     no    no           3 seconds ago
2     134.209.14.170   8080   US  ...     no    no            1 minute ago
3     104.168.211.80   8080   US  ...     no    no            1 minute ago
4     65.152.119.226  44844   US  ...     no   yes            1 minute ago
..               ...    ...  ...  ...    ...   ...                     ...
195     50.249.79.18   8080   US  ...     no    no  7 hours 41 minutes ago
196   198.23.173.100   8080   US  ...     no    no  7 hours 41 minutes ago
197  185.255.130.100   8080   US  ...     no    no  7 hours 41 minutes ago
198    74.214.177.61   8080   US  ...     no    no  7 hours 41 minutes ago
199  102.129.225.215   3129   US  ...     no   yes  7 hours 42 minutes ago
于 2019-08-22T15:01:48.233 回答