【问题标题】:scraping AJAX content on webpage with requests python使用请求 python 在网页上抓取 AJAX 内容
【发布时间】:2019-04-26 12:08:42
【问题描述】:

我正在尝试在不执行 javascript 的情况下在网页上抓取 AJAX 加载的部分。通过使用 Chrome 开发工具,我发现 AJAX 容器正在通过 POST 请求从 URL 中提取内容,因此我想使用 python requests 包复制请求。但奇怪的是,通过使用 Chrome 提供的Headers 信息,我总是得到 400 错误,从 Chrome 复制的 curl 命令也会发生同样的情况。所以我想知道是否有人可以分享一些见解。

我感兴趣的网站是here。使用 Chrome:ctrl-shift-I、network、XHR,我想要的部分是“内容”。我正在使用的脚本是:

headers = {"authority": "cafe.bithumb.com",
    "path": "/boards/43/contents",
    "method": "POST",
    "origin":"https://cafe.bithumb.com",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
    "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36",
    "accept-encoding":"gzip, deflate, br",
    "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
    "accept":"application/json, text/javascript, */*; q=0.01",
    "referer":"https://cafe.bithumb.com/view/boards/43",
    "x-requested-with":"XMLHttpRequest",
    "scheme": "https",
    "content-length":"1107"}
s=requests.Session()
s.headers.update(headers)
r = s.post('https://cafe.bithumb.com/boards/43/contents')

【问题讨论】:

    标签: python html ajax python-requests


    【解决方案1】:

    你只需要比较两个帖子数据,然后你会发现它们几乎相同,除了几个参数(draw=page...start=xx)。这意味着您可以通过修改 drawstart 来抓取 Ajax 数据。

    编辑:数据已转换为字典,因此我们不需要 urlencode,也不需要 cookie(我测试过)。

    import requests
    import json
    
    headers = {
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Origin": "https://cafe.bithumb.com",
            "X-Requested-With": "XMLHttpRequest",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36",
            "DNT": "1",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Referer": "https://cafe.bithumb.com/view/boards/43",
            "Accept-Encoding": "gzip, deflate, br"
        }
    
    string = """columns[0][data]=0&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=false&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=1&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=false&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=2&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=false&columns[2][search][value]=&columns[2][search][regex]=false&columns[3][data]=3&columns[3][name]=&columns[3][searchable]=true&columns[3][orderable]=false&columns[3][search][value]=&columns[3][search][regex]=false&columns[4][data]=4&columns[4][name]=&columns[4][searchable]=true&columns[4][orderable]=false&columns[4][search][value]=&columns[4][search][regex]=false&start=30&length=30&search[value]=&search[regex]=false"""
    
    
    article_root = "https://cafe.bithumb.com/view/board-contents/{}"
    
    for page in range(1,4):
        with requests.Session() as s:
            s.headers.update(headers)
    
            data = {"draw":page}
            data.update( { ele[:ele.find("=")]:ele[ele.find("=")+1:] for ele in string.split("&") } )
            data["start"] = 30 * (page - 1)
    
            r = s.post('https://cafe.bithumb.com/boards/43/contents', data = data, verify = False) # set verify = False while you are using fiddler
    
            json_data = json.loads(r.text).get("data") # transform string to dict then we can extract data easier
            for each in json_data:
                url = article_root.format(each[0])
                print(url)
    

    【讨论】:

    • 感谢@kcorlidy,您的代码就像一个魅力。我是新手,请您详细说明:1.如何比较两个帖子数据?我的问题中的代码试图复制我从 chrome 开发工具获得的内容,但我无法拦截原始请求。 2. 请问data是从哪里得到的? 3.你的代码获取了第二页的内容,我试过page =0但它不起作用,我应该如何更改代码? 4. 与 chrome 中的 ~0.5 相比,似乎需要 3-4 秒才能得到响应,这是否正常?很抱歉给您一连串的问题,非常感谢!
    • @Lampard 1 and 2.use fiddler 3.there is no page zero, page > 0. 4.这是正常的,为什么你需要3-4秒,因为你正在建立一个新的连接。我会编辑我的答案来告诉你该怎么做
    • @Lampard 很抱歉,因为我一开始还没有访问第 2 页。我发现响应取决于drawstart。我已经编辑了我的答案并与浏览器的响应进行了比较(相同)
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2019-11-05
    • 1970-01-01
    • 2018-03-22
    • 2016-02-21
    • 1970-01-01
    相关资源
    最近更新 更多