Python 爬虫项目:如何抓取“知乎”上所有的问题与答案? 在今天的互联网时代,我们几乎可以通过互联网查阅到我们所需要的任何问题的答案。而在知乎上,有着海量的高质量问题和答案。本篇文章将介绍如何使用 Python 爬虫来获取知乎上的所有问题和答案。 一、分析目标 在开始爬取之前,我们需要确定我们想要获取的数据的具体目标。在我们的例子中,我们需要获取知乎上所有的问题和答案,这包括每个问题的标题、问题描述以及每个答案的作者、内容等信息。 二、分析页面 当我们确定了目标之后,我们需要对知乎网站进行详细分析,以便我们能够编写出爬虫程序来抓取所需要的数据。 在知乎网站上,每个问题页面的 URL 地址都以“https://www.zhihu.com/question/”开头,后面接上对应的问题 ID。例如,如果我们要抓取的是“如何学习 Python 编程语言?”这个问题页面的数据,那么对应的 URL 地址就是“https://www.zhihu.com/question/20583933”。 当我们进入一个问题页面后,我们可以看到该问题的标题和问题描述。而在页面的右侧,我们可以看到所有回答的摘要。如果我们想要查看完整的答案,我们可以单击该摘要,跳转到相应的答案页面。 因此,如果我们要获取知乎上的所有问题和答案,我们需要进行以下步骤: 1. 首先,我们需要获取知乎上所有的问题 ID,以便能够访问每个问题页面。 2. 然后,我们需要在问题页面中抓取每个问题的标题和描述。 3. 最后,我们需要进入每个答案页面,以获取每个答案的作者和内容。 三、编写爬虫程序 现在我们已经知道了我们要查找的数据和如何获取它。接下来,我们将写一个 Python 程序来实现这个目标。 首先,我们需要导入必要的库,如 requests 和 Beautiful Soup。代码如下所示: ``` import requests from bs4 import BeautifulSoup ``` 然后,我们需要定义一个函数来获取知乎上所有的问题 ID。知乎的问题 ID 是一个数字,我们可以在知乎网站上找到每个问题的 ID。 ``` def get_question_ids(): """ 获取知乎上所有问题的 ID """ question_ids = [] for i in range(1, 10): url = f'https://www.zhihu.com/node/ExploreAnswerListV2?params=%7B%22offset%22%3A{i*5-5}%2C%22type%22%3A%22day%22%7D' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') data = soup.find_all('a', class_='question_link') for d in data: question_ids.append(d['href'].split('/')[-1]) return question_ids ``` 在这个函数中,我们首先定义了一个空列表 question_ids,用来存储所有的问题 ID。然后,我们循环访问知乎上的每个问题页面,从中获取每个问题的 ID。我们使用 BeautifulSoup 库来解析 HTML 页面,并找到 class 为 question_link 的元素,这些元素包含了所有的问题 URL。 在获取了所有的问题 ID 之后,我们需要编写一个函数来获取每个问题的标题和描述。代码如下所示: ``` def get_question_data(question_id): """ 获取知乎问题的标题和描述 """ url = f'https://www.zhihu.com/question/{question_id}' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') title = soup.find('h1', class_='QuestionHeader-title').text.strip() desc = soup.find('div', class_='QuestionHeader-detail').text.strip() return title, desc ``` 在这个函数中,我们首先构造问题页面的 URL 地址,并使用 requests 库发送请求。然后,我们使用 BeautifulSoup 库解析 HTML 页面,并找到 class 为 QuestionHeader-title 和 QuestionHeader-detail 的元素,这些元素包含了问题的标题和描述。 最后,我们需要编写一个函数来获取每个答案的作者和内容。代码如下所示: ``` def get_answer_data(answer_url): """ 获取知乎答案的作者和内容 """ headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(answer_url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') author = soup.find('span', class_='UserLink AuthorInfo-name').text.strip() content = soup.find('div', class_='RichContent-inner').text.strip() return author, content ``` 在这个函数中,我们首先构造答案页面的 URL 地址,并使用 requests 库发送请求。然后,我们使用 BeautifulSoup 库解析 HTML 页面,并找到 class 为 UserLink AuthorInfo-name 和 RichContent-inner 的元素,这些元素包含了答案的作者和内容。 最后,我们可以编写一个函数来遍历所有的问题页面,并调用之前的函数来获取每个问题和答案的数据。代码如下所示: ``` if __name__ == '__main__': question_ids = get_question_ids() for question_id in question_ids: title, desc = get_question_data(question_id) print(f'标题:{title}') print(f'描述:{desc}') url = f'https://www.zhihu.com/question/{question_id}/answer' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') data = soup.find_all('div', class_='List-item') for d in data: answer_url = d.find('a')['href'] author, content = get_answer_data(answer_url) print(f'作者:{author}') print(f'内容:{content}') ``` 在这个函数中,我们首先调用 get_question_ids() 函数来获取所有的问题 ID。然后,我们遍历所有的问题 ID,并调用 get_question_data() 函数来获取每个问题的标题和描述。接着,我们构造答案页面的 URL 地址,并使用 BeautifulSoup 库解析 HTML 页面,以获取每个答案的作者和内容。 四、总结 在本篇文章中,我们介绍了如何使用 Python 爬虫来获取知乎上的所有问题和答案。我们首先分析了我们需要获取的数据,并分析了页面结构。然后,我们编写了 Python 程序来实现我们的目标,包括获取问题 ID、获取问题的标题和描述以及获取答案的作者和内容。 如果你想获取更多的数据,你可以继续改进代码,例如获取回答的点赞数、评论数等等。