Python中使用Scrapy爬取知乎内容,为什么获取的和原网页不一样?
新手刚开始学习. https://segmentfault.com/q/1010000008939688 这里有详细描述.谢谢.
Python中使用Scrapy爬取知乎内容,为什么获取的和原网页不一样?
这是反爬策略吧
这个问题很常见,通常是因为知乎这类网站大量使用了JavaScript动态加载内容,而Scrapy默认只抓取初始的HTML静态页面。
简单说,你看到的“原网页”是浏览器执行了所有JS代码后的最终结果,而Scrapy拿到的是服务器最初返回的、还没被JS修改的“骨架”HTML。里面的很多数据(比如回答内容、评论)都是通过后续的AJAX请求加载的。
要解决这个问题,你有几个选择:
- 分析网络请求:用浏览器的开发者工具(F12 -> Network),找到实际加载数据的那个XHR/Fetch请求,直接用Scrapy去模拟请求那个API接口。这通常是最直接有效的方法。
- 使用Splash或Selenium:让Scrapy通过一个真正的浏览器(如Chrome)来渲染页面,拿到完整的DOM。但这会慢很多,资源消耗也大。
- 寻找隐藏数据:有时数据会以JSON格式藏在页面的
<script>标签里,你可以用正则表达式或json模块把它提取出来。
核心建议:别爬页面,去爬它背后提供数据的API。
举个例子,假设你发现知乎某个问题页面的数据是通过一个像 https://www.zhihu.com/api/v4/questions/123456/answers?... 这样的接口返回的。你的Scrapy爬虫就可以直接请求这个URL:
import scrapy
import json
class ZhihuSpider(scrapy.Spider):
name = 'zhihu'
start_urls = ['https://www.zhihu.com/api/v4/questions/123456/answers?include=data[*].content&limit=20&offset=0']
def parse(self, response):
# 解析返回的JSON数据
data = json.loads(response.text)
for answer in data.get('data', []):
# 提取你需要的信息,比如回答内容
content = answer.get('content', '')
# ... 处理或保存 content
yield {'content': content}
# 处理分页,如果存在的话
if data.get('paging', {}).get('is_end') is False:
next_page_url = data['paging']['next']
yield scrapy.Request(url=next_page_url, callback=self.parse)
总结:直接去抓数据接口,别跟渲染后的页面较劲。
用到什么策略,可以详细说说吗?还有如何解决呢?谢谢.
你可以用 chromedrive 试试 如果还是不一样 那就说明确实有反爬的问题~
可能是页面异步获取了其他内容,所以直接抓取看不到,其中策略比较多
有问题可以加我们的群问,这样效率更高,这个群是一群工程师组建的面向初学者的 python Linux 学习群( qq 群号: 278529278 ) 非商业性质,拒绝广告,只接收真正想学这方面技术的朋友,交流学习,申请请说明来自 v2ex
好多异步请求
我也以为是异步,可是禁用 js 后的页面和我获取的页面还是不一样
好的,我试试..谢谢.
javascript ,
直接抓现成的 json 包,伪装客户端发包
你说的原网页是指的网页源代码还是审查元素?审查元素的代码是经过 js 渲染过的,不一样是很正常的,这个要以网页源代码的为标准,如果网页源代码和爬虫爬的不一样,另说,有可能是防爬。
网页源代码不一样...主要是一个 css 文件不一样,结果导致我写的 xpath 和 response.css 全部为空...这种是防爬吗?
应该是防爬了,防爬一般来就是根据 header 和 cookie 下文章,再有就是根据 ip 频率
不是防爬,还是 js 问题,我用 selenium+Phantomjs 成功解决.
如果是 js 问题,那么网页源代码和你抓取的应该是一样的,你用 Phantomjs ,还是因为有些 dom 是 js 动态生成的。

