如何使用“请求-HTML库”点击“下一步”进行分页

时间:2019-05-20 23:27:38

标签: python-3.6 python-requests-html

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

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

我对'requests-html'的理解是,它基本上是通过控制无头铬实例并使用它来呈现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文档的发现路径(它当然是在request-html中使用的),它似乎揭示了一个非常简单的'.click()'方法,该方法似乎并未阻塞下一个的xpath选择器我喂它的按钮。不幸的是,我仍然看不到任何证据可以成功单击该链接,并且不断收到错误消息:“ RuntimeWarning:从未等待协程'clickNext'”。

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

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

异步定义clickNext():

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

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

到目前为止,我对异步编程和协程的使用经验为零,因此我想他是在深入研究这个问题,但是如果有人对我在做什么方面有任何见解,我将非常感谢您关心的任何信息分享。谢谢!

1 个答案:

答案 0 :(得分:0)

因此,您实际上不需要渲染JS即可获取全部10页。根据最初的要求,所有10页都作为一个大表提供,然后进行分页。因此,使用request_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