How to get the body of an answer using the Stack Exchange API?
Asked Answered
R

2

5

I am using StackAPI to get the most voted questions and the most voted answers to those questions:-

from stackapi import StackAPI
SITE = StackAPI('stackoverflow')
SITE.max_pages=1
SITE.page_size=10

questions = SITE.fetch('questions', min=20, tagged='python', sort='votes')
for quest in questions['items']:
    if 'title' not in quest or quest['is_answered'] == False:
        continue
    title = quest['title']
    print('Question :- {0}'.format(title))
    question_id = quest['question_id']
    print('Question ID :- {0}'.format(question_id))
    top_answer = SITE.fetch('questions/' + str(question_id) + '/answers', order = 'desc', sort='votes')
    print('Most Voted Answer ID :- {0}'.format(top_answer['items'][0]['answer_id']))

Now using this answer_id I would like to get the body of that answer. I can get the rest of the details by using this API link.

Reptant answered 12/12, 2018 at 16:41 Comment(0)
P
8

Refer to these posts on Stack Apps:

  1. Get questions with body and answers
  2. How to get Question/Answer body in the API response using filters?
  3. My filter is not returning any results. How to create a minimal filter?

You need to use a custom filter to get question/answer/post bodies.

The good news is that you can also use the custom filter to get the answer data at the same time as you get the questions -- eliminating the need for later API calls.

For example, if you call the /questions route with the filter:
    !*SU8CGYZitCB.D*(BDVIficKj7nFMLLDij64nVID)N9aK3GmR9kT4IzT*5iO_1y3iZ)6W.G*

You get results like:

"items": [ {
    "tags": ["python", "iterator", "generator", "yield", "coroutine"],
    "answers": [ {
        "owner": {"user_id": 8458, "display_name": "Douglas Mayle"},
        "is_accepted": false,
        "score": 248,
        "creation_date": 1224800643,
        "answer_id": 231778,
        "body": "<p><code>yield</code> is just like <code>return</code> - it returns what..."
        }, {
        "owner": {"user_id": 22656, "display_name": "Jon Skeet"},
        "is_accepted": false,
        "score": 139,
        "creation_date": 1224800766,
        "answer_id": 231788,
        "body": "<p>It's returning a generator. I'm not particularly familiar with Python, ..."
        }, {
        ...
    } ],
    "owner": {"user_id": 18300, "display_name": "Alex. S."},
    "is_answered": true,
    "accepted_answer_id": 231855,
    "answer_count": 40,
    "score": 8742,
    "creation_date": 1224800471,
    "question_id": 231767,
    "title": "What does the &quot;yield&quot; keyword do?"
    },
    ...

So, change this:

questions = SITE.fetch('questions', min=20, tagged='python', sort='votes')

To something like this:

questions = SITE.fetch('questions', min=20, tagged='python', sort='votes', filter='!*SU8CGYZitCB.D*(BDVIficKj7nFMLLDij64nVID)N9aK3GmR9kT4IzT*5iO_1y3iZ)6W.G*')

then adjust your for loop accordingly.

Parquet answered 12/12, 2018 at 21:49 Comment(0)
A
0

You can use such script. You must define question id before

question_id = 62232252
url = f'https://api.stackexchange.com/2.3/questions/{question_id}/answers'
params = {
    'order': 'asc',
    'sort': 'votes',    
    'site': 'stackoverflow',       
    'filter': 'withbody',    
}

response = requests.get(url, params=params)
answers = response.json()

from bs4 import BeautifulSoup

cleaned_answers = ''
for answer in answers['items']:
    if answer['score'] >= 0:
      soup = BeautifulSoup(answer['body'], 'html.parser')
      clean_text = soup.get_text()
      cleaned_answers += clean_text.strip()
      print(clean_text.strip())
      print('-' * 50)

output:

this article helped a lot, because I had the same issue.
But there are still some things to be respected:

Ensure that nmap_path is a list or a tuple, not a single str.
when defining the path, it needs to be noted with a leading dot "."

import nmap # networ scanner "nmap" needs also the nmap tool from https://nmap.org/download

# nmap ping scan
#s_path=(r'C:\Program Files (x86)\Nmap\nmap.exe',r'\Nmap\nmap.exe',r'\nmap-7.92\nmap.exe')
s_path=[r'\Nmap\nmap.exe',r'.\nmap-7.92\nmap.exe']
print(type(s_path))
nm = nmap.PortScanner(nmap_search_path = s_path) # alternative way with seld defined path
#nm = nmap.PortScanner() #standard way, if Nmap tool is installed correct from https://nmap.org/download
nm.scan(hosts="192.168.178.0/24",arguments="-sn")
ip_list=nm.all_hosts() #returns a list with all available IPs
print(ip_list)
--------------------------------------------------
You need to add path for nmap.exe while initializing PortScanner 
import nmap

nmap_path = r"C:\Program Files (x86)\Nmap\nmap.exe"
nmap.PortScanner(nmap_search_path = nmap_path)
--------------------------------------------------
I know this is old thread. But if someone is searching for similar answer.
What @sushanth answered is correct.
It just has to be list:
nmap_path = [r"C:\Program Files (x86)\Nmap\nmap.exe",]
scanner = nmap.PortScanner(nmap_search_path=nmap_path)
--------------------------------------------------
Audrieaudris answered 15/9 at 20:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.