如何将网页抓取正确地实现到我的api中

时间:2019-09-09 08:30:35

标签: python django web-scraping django-rest-framework django-views

我正在制作一个Django API,该API可以向用户返回单词的定义,该单词是通过使用word =(在此处放置单词)网址来查找该单词的,此api会抓取dictionary.com以获取定义如果它在我的数据库中还不存在,则将其添加到我的数据库(如果它们存在于他们的站点中)。我只是想弄清楚如何正确地正确构造它,而不是仅仅将它放入我的视图中。如果希望通过删除他们的推荐在数据库或他们的网站上找不到任何单词,我可以将json返回给最终用户并给出建议。

如果发生404错误,我尝试在视图内返回json响应。我总是在假设我的整个结构是错误的情况下抛出错误。

# the queryset for a view
def get_queryset(self):
    # this gets the word put into the url
    word = self.kwargs['word']
    headers = {"User-Agent": "user agent stuff"}
    # this checks if it exists in the database
    if not Word.objects.filter(word=word).exists():
        #this is the web scrapping
        page = requests.get(f"https://www.dictionary.com/browse/{word}?s=t", headers=headers)
        soup = BeautifulSoup(page.content, 'html.parser')
        try:
            output = soup.find("div",{"value": "1"}).get_text()
            # this saves the web scrapped info to the database
            test = Word(word=self.kwargs['word'].strip(), meaning=output)
            test.save()
        except:
            return
    # this returns the word and definition
    return Word.objects.all()

我希望用户能够获得一个定义,只要该词存在还是无法返回我从网上抓取的建议以供他们选择。

1 个答案:

答案 0 :(得分:0)

get_queryset可能不是放置抓取逻辑的正确位置。相反,您想使用模型的默认查询集来查看是否有定义,如果没有,则对第三方api执行查询,将响应存储到数据库中并将定义返回给用户。

概述

class WordViewSet(viewsets.ModelViewSet):
    queryset = Word.objects.all()
    serializer_class = WordSerializer

    def retrieve(self, request, pk=None):
        word = Word.objects.find(id=pk)
        if not word:
            # query 3rd party api
            res = requests.get('dictionary.com', params={'q': request.param['word']})
            word = res.json()['definition']
            word = Word('title': ..., 'definition': ...)
            word.save()
        serializer = WordSerializer(word)
        return Response(serializer.data)