Code Monkey home page Code Monkey logo

Comments (25)

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024 32

有的,今天学习了学长的第六章 Ajax数据爬取。也发现了这个问题,但我想学长写书的目的教的是方法,利用书中所授方法我找到了如下方式抓取。

首先,我观察几次的ajax的url,并没有发现什么规律
Request URL:https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4464249252756977
每次都不一样,而且毫无规律可循。就在想他们是怎么通过本次的请求得到下次的since_id的,肯定是哪传递了这个参数

仔细观察,发现since_id实际上是本次刷新出来的最开始的那条微博的id
再仔细观察几个xhr之间的关系,发现每次的xhr的preview里的.data.cardlistInfo里有一个since_id,而这个since_id正好是下一次url里的since_id,也就是下一次的第一条微博的id。而第一次的xhr的url里并没有since_id,因为他是第一个。(实际上仔细看书会发现新浪就是把page换成了since_id,位置都没变,其他参数也都没变)

得到了以上信息,我们就可以在原始代码上进行修改。
get_page()函数作如下修改:(省略部分保持不变)
def get_page(since_id):
params = {
'type': 'uid',
'value': '2830678474',
'containerid': '1076032830678474'
}
if since_id!=0:
params['since_id'] = since_id

main作如下修改:(省略部分保持不变)
if name == 'main':
since_id = 0
for page in range(1, max_page + 1):
json = get_page(since_id)
since_id = json.get('data').get('cardlistInfo').get('since_id')

运行结果无误!~

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024 5

我终于知道为什么楼上两位会返回tuple了,是因为get_page函数的问题。也是因为我的疏忽,起到了极大的误导性。

问题是这样的,我是照着书写的,楼上两位是照着GitHub上的代码写的,而二者的代码是不一样的。在【stevenshuang committed on 18 May 2018】这次更新中,由于微博API的更新,对get_page()函数进行了修改,对get_page()的返回值,由response.json()改成了两个response.json(), page。这也是楼上两位出现返回值是tuple的根本原因。也是我在【LiuZhH1366 commented on 26 Jan】回复中不严谨的一个问题所在。

所以就有了【hannzhao commented 5 days ago】中的以下内容:

@LiuZhH1366 您好,非常感谢您的代码。但是我执行的时候遇到了一点小问题。
main函数中的json = get_page(since_id)返回的是tuple元组,元组中有两个元素,第一个是json的字典,第二个是变量 页数page。这时候变量json不能直接用.get()方法,我把下一句改成了
since_id = json[0].get('data').get('cardlistInfo').get('since_id') 也就是把json改为了json[0],这样就可以正常输出啦

两个元素,一个是json,一个是page,但是还能正确的跑

当然我还要肯定一点的是,本项目中的代码【https://github.com/Python3WebSpider/WeiboList/blob/master/weibo.py 】还能跑,而且能正确的跑,这是为什么?为什么page参数都没了还能用?
谜底揭晓,因为他只是把参数换了,可原来的json数据还在。就是说以下两个页面主要内容是一致的。(经过文本比对之后得到的结论)
https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4471555595691396
https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&page=2

So,我的结论就是这些,希望能帮到更多的人~

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024 2

经测试,你出现的问题在于,headers里的host写的是m.weibo.com,应该是.cn。
改完再试试看,2.19 18:09测试可行

from weibolist.

Thousand-Sunnny avatar Thousand-Sunnny commented on July 21, 2024 2

我知道为什么了,必须要去域名为.cn的那个微博网站https://m.weibo.cn/u/2830678474
直接百度搜索出来的微博网站不行,找不到getindex条目

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024 1

我知道为什么了,必须要去域名为.cn的那个微博网站https://m.weibo.cn/u/2830678474
直接百度搜索出来的微博网站不行,找不到getindex条目

对的,有两个点,一个是手机版一般会比电脑版的页面更好爬取,所以选取的是m.weibo.cn而不是weibo.com,另一个是要想找到ajax的请求首先得先触发它,这里也就是页面得往下滑。

from weibolist.

Germey avatar Germey commented on July 21, 2024

感谢!

from weibolist.

A1bertY avatar A1bertY commented on July 21, 2024

2020年2月19日测试无效,目前微博更新了api,即使模拟了请求头和url也无法使用requests获取到内容,但是用浏览器却可以,不知为何,等待高手解答,下面是代码
import requests
headers={
'Host':'m.weibo.com',
'Referer':'https://m.weibo.cn/u/2830678474',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.116 Safari/537.36',
'X-Requested-With':'XMLHttpRequest',
'upgrade-insecure-requests': '1',
'sec-fetch-site': 'same-origin',
'sec-fetch-mode': 'same-origin',
'sec-fetch-dest': 'empty',
'cache-control': 'max-age=0',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
}
r=requests.get('https://m.weibo.cn/api/container/getindex?type=uid&value=2830678474&containerid=1076032830678474',headers=headers)
print(r.text)

下面是运行结果
{
"ok": 0,
"code": 516,
"msg": "CONTROLLER_ERROR"
}

通过浏览器的开发者窗口观察到,请求头部还有一些带冒号的请求头,应该是和HTTP2有关

from weibolist.

A1bertY avatar A1bertY commented on July 21, 2024

经测试,你出现的问题在于,headers里的host写的是m.weibo.com,应该是.cn。
改完再试试看,2.19 18:09测试可行

测试通过!错误定位十分精准!非常感谢!

from weibolist.

hannzhao avatar hannzhao commented on July 21, 2024

@LiuZhH1366 您好,非常感谢您的代码。但是我执行的时候遇到了一点小问题。
main函数中的json = get_page(since_id)返回的是tuple元组,元组中有两个元素,第一个是json的字典,第二个是变量 页数page。这时候变量json不能直接用.get()方法,我把下一句改成了
since_id = json[0].get('data').get('cardlistInfo').get('since_id') 也就是把json改为了json[0],这样就可以正常输出啦

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024

@LiuZhH1366 您好,非常感谢您的代码。但是我执行的时候遇到了一点小问题。
main函数中的json = get_page(since_id)返回的是tuple元组,元组中有两个元素,第一个是json的字典,第二个是变量 页数page。这时候变量json不能直接用.get()方法,我把下一句改成了
since_id = json[0].get('data').get('cardlistInfo').get('since_id') 也就是把json改为了json[0],这样就可以正常输出啦

我用了好久也没复现出你说的小问题(返回tuple,我这边返回的都是json的字典),希望能借代码一看,我猜可能是get_page()函数返回值不太一样。
以下是我的这部分代码,供你参考,如还有问题,请借代码一看,我再仔细试试。

def get_page(since_id):
    params = {
        'type': 'uid',
        'value': '2830678474',
        'containerid': '1076032830678474'
    }
    if since_id!=0:
        params['since_id'] = since_id
    url = base_url + urlencode(params)
    try:
        response = requests.get(url, headers=headers)
        if response.status_code == 200:
            return response.json()
    except requests.ConnectionError as e:
        print('Error', e.args)

if __name__ == '__main__':
    since_id = 0
    for page in range(1, max_page + 1):
        json = get_page(since_id)
        since_id = json.get('data').get('cardlistInfo').get('since_id')
        results = parse_page(json)
        for result in results:
            try:
                print(result)
            except:
                print('='*10+"此内容无法显示"+"="*10)

from weibolist.

literence avatar literence commented on July 21, 2024

since_id = json.get('data').get('cardlistinfo').get('since_id')
这行代码提示错误信息
AttributeError: 'tuple' object has no attribute 'get'
谁能解答一下

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024

since_id = json.get('data').get('cardlistinfo').get('since_id')
这行代码提示错误信息
AttributeError: 'tuple' object has no attribute 'get'
谁能解答一下

我还是想说一句,问的时候要把代码发全,就这么一句,复现都复现不了,怎么帮你呀、、
但是呢,我还是发现了问题,一个低级错误,cardlistInfo抄错了,大写I抄成了小写i
然后我也试了,但是咱们报的错还不太一样(AttributeError: 'NoneType' object has no attribute 'get'),所以希望能帮到你吧

from weibolist.

forever0830 avatar forever0830 commented on July 21, 2024

有的,今天学习了学长的第六章 Ajax数据爬取。也发现了这个问题,但我想学长写书的目的教的是方法,利用书中所授方法我找到了如下方式抓取。

首先,我观察几次的ajax的url,并没有发现什么规律
Request URL:https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4464249252756977
每次都不一样,而且毫无规律可循。就在想他们是怎么通过本次的请求得到下次的since_id的,肯定是哪传递了这个参数

仔细观察,发现since_id实际上是本次刷新出来的最开始的那条微博的id
再仔细观察几个xhr之间的关系,发现每次的xhr的preview里的.data.cardlistInfo里有一个since_id,而这个since_id正好是下一次url里的since_id,也就是下一次的第一条微博的id。而第一次的xhr的url里并没有since_id,因为他是第一个。(实际上仔细看书会发现新浪就是把page换成了since_id,位置都没变,其他参数也都没变)

得到了以上信息,我们就可以在原始代码上进行修改。
get_page()函数作如下修改:(省略部分保持不变)
def get_page(since_id):
params = {
'type': 'uid',
'value': '2830678474',
'containerid': '1076032830678474'
}
if since_id!=0: params['since_id'] = since_id

main作如下修改:(省略部分保持不变)
if name == 'main':
since_id = 0
for page in range(1, max_page + 1):
json = get_page(since_id) since_id = json.get('data').get('cardlistInfo').get('since_id')

运行结果无误!~

有的,今天学习了学长的第六章 Ajax数据爬取。也发现了这个问题,但我想学长写书的目的教的是方法,利用书中所授方法我找到了如下方式抓取。

首先,我观察几次的ajax的url,并没有发现什么规律
Request URL:https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4464249252756977
每次都不一样,而且毫无规律可循。就在想他们是怎么通过本次的请求得到下次的since_id的,肯定是哪传递了这个参数

仔细观察,发现since_id实际上是本次刷新出来的最开始的那条微博的id
再仔细观察几个xhr之间的关系,发现每次的xhr的preview里的.data.cardlistInfo里有一个since_id,而这个since_id正好是下一次url里的since_id,也就是下一次的第一条微博的id。而第一次的xhr的url里并没有since_id,因为他是第一个。(实际上仔细看书会发现新浪就是把page换成了since_id,位置都没变,其他参数也都没变)

得到了以上信息,我们就可以在原始代码上进行修改。
get_page()函数作如下修改:(省略部分保持不变)
def get_page(since_id):
params = {
'type': 'uid',
'value': '2830678474',
'containerid': '1076032830678474'
}
if since_id!=0: params['since_id'] = since_id

main作如下修改:(省略部分保持不变)
if name == 'main':
since_id = 0
for page in range(1, max_page + 1):
json = get_page(since_id) since_id = json.get('data').get('cardlistInfo').get('since_id')

今天看见连since_id都没了

from weibolist.

literence avatar literence commented on July 21, 2024

我终于知道为什么楼上两位会返回tuple了,是因为get_page函数的问题。也是因为我的疏忽,起到了极大的误导性。

问题是这样的,我是照着书写的,楼上两位是照着GitHub上的代码写的,而二者的代码是不一样的。在【stevenshuang committed on 18 May 2018】这次更新中,由于微博API的更新,对get_page()函数进行了修改,对get_page()的返回值,由response.json()改成了两个response.json(), page。这也是楼上两位出现返回值是tuple的根本原因。也是我在【LiuZhH1366 commented on 26 Jan】回复中不严谨的一个问题所在。

所以就有了【hannzhao commented 5 days ago】中的以下内容:

@LiuZhH1366 您好,非常感谢您的代码。但是我执行的时候遇到了一点小问题。
main函数中的json = get_page(since_id)返回的是tuple元组,元组中有两个元素,第一个是json的字典,第二个是变量 页数page。这时候变量json不能直接用.get()方法,我把下一句改成了
since_id = json[0].get('data').get('cardlistInfo').get('since_id') 也就是把json改为了json[0],这样就可以正常输出啦

两个元素,一个是json,一个是page,但是还能正确的跑

当然我还要肯定一点的是,本项目中的代码【https://github.com/Python3WebSpider/WeiboList/blob/master/weibo.py 】还能跑,而且能正确的跑,这是为什么?为什么page参数都没了还能用?
谜底揭晓,因为他只是把参数换了,可原来的json数据还在。就是说以下两个页面主要内容是一致的。(经过文本比对之后得到的结论)
https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4471555595691396
https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&page=2

So,我的结论就是这些,希望能帮到更多的人~

终于明白了,谢谢大佬

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024

@forever0830 今天看见连since_id都没了

我刚试了一下,since_id还在,你得往下翻他才会触发
搜狗截图20200227173854

from weibolist.

lziiid avatar lziiid commented on July 21, 2024

求助 现在微博的ajax请求和书上的好像完全不一样了 怎么办。。

from weibolist.

LiuZhH1366 avatar LiuZhH1366 commented on July 21, 2024

求助 现在微博的ajax请求和书上的好像完全不一样了 怎么办。。

[捂脸]我刚看了一下,好像还和上边的回复一样,应该是没变,建议你先仔细把书看看(书上大部分内容目前依旧有效),然后参考上边的回复以及开发者工具中你所看到的内容进行尝试,遇到实际问题再来求助。

from weibolist.

lziiid avatar lziiid commented on July 21, 2024

求助 现在微博的ajax请求和书上的好像完全不一样了 怎么办。。

[捂脸]我刚看了一下,好像还和上边的回复一样,应该是没变,建议你先仔细把书看看(书上大部分内容目前依旧有效),然后参考上边的回复以及开发者工具中你所看到的内容进行尝试,遇到实际问题再来求助。

微信图片_20200412164456
我看到的是这样的呀。。请求头里边的参数也和书上的不一样了

from weibolist.

Thousand-Sunnny avatar Thousand-Sunnny commented on July 21, 2024

求助 现在微博的ajax请求和书上的好像完全不一样了 怎么办。。

[捂脸]我刚看了一下,好像还和上边的回复一样,应该是没变,建议你先仔细把书看看(书上大部分内容目前依旧有效),然后参考上边的回复以及开发者工具中你所看到的内容进行尝试,遇到实际问题再来求助。

微信图片_20200412164456
我看到的是这样的呀。。请求头里边的参数也和书上的不一样了

我也是这样,找不到那个getindex了

from weibolist.

thhou avatar thhou commented on July 21, 2024

建议大家使用 @LiuZhH1366 更改之后的代码,即采用since_id而非page,当然parse_page函数也要做相应修改(把page形参去掉)。因为用page爬取不完整:
微博图
爬取图

from weibolist.

heliusjing avatar heliusjing commented on July 21, 2024

原程序是可以正常跑的,page参数还是可以正常使用 的

from weibolist.

wongbng avatar wongbng commented on July 21, 2024

学习了,各位大神。现在链接中多了display=0&retcode=6102,发现没有这个display=0&retcode=6102,程序照样运行
https://m.weibo.cn/api/container/getIndex?display=0&retcode=6102&type=uid&value=2830678474&containerid=1076032830678474&since_id=4556771409006204

from weibolist.

huang-biao avatar huang-biao commented on July 21, 2024

有的,今天学习了学长的第六章 Ajax数据爬取。也发现了这个问题,但我想学长写书的目的教的是方法,利用书中所授方法我找到了如下方式抓取。

首先,我观察几次的ajax的url,并没有发现什么规律
Request URL:https://m.weibo.cn/api/container/getIndex?type=uid&value=2830678474&containerid=1076032830678474&since_id=4464249252756977
每次都不一样,而且毫无规律可循。就在想他们是怎么通过本次的请求得到下次的since_id的,肯定是哪传递了这个参数

仔细观察,发现since_id实际上是本次刷新出来的最开始的那条微博的id
再仔细观察几个xhr之间的关系,发现每次的xhr的preview里的.data.cardlistInfo里有一个since_id,而这个since_id正好是下一次url里的since_id,也就是下一次的第一条微博的id。而第一次的xhr的url里并没有since_id,因为他是第一个。(实际上仔细看书会发现新浪就是把page换成了since_id,位置都没变,其他参数也都没变)

得到了以上信息,我们就可以在原始代码上进行修改。
get_page()函数作如下修改:(省略部分保持不变)
def get_page(since_id):
params = {
'type': 'uid',
'value': '2830678474',
'containerid': '1076032830678474'
}
if since_id!=0: params['since_id'] = since_id

main作如下修改:(省略部分保持不变)
if name == 'main':
since_id = 0
for page in range(1, max_page + 1):
json = get_page(since_id) since_id = json.get('data').get('cardlistInfo').get('since_id')

运行结果无误!~

你好,你可以直接把修改好的整个代码发出来吗,发一句缺斤少两的代码,想运行都失败。无奈

from weibolist.

longchengguxiao avatar longchengguxiao commented on July 21, 2024

想问一下如何用beautifulsoup实现这个呢,bs4如何解析json格式呀

from weibolist.

MGMCN avatar MGMCN commented on July 21, 2024

为什么要用beautifulsoup解析json呢?直接用json库解析不就得了。而且beautifulsoup主要针对的是HTML/XML的解析。😂

from weibolist.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.