【问题标题】:Displaying scraped results in Django template在 Django 模板中显示抓取的结果
【发布时间】:2011-02-27 15:15:57
【问题描述】:

我正在测试用 django 构建一个抓取网站。出于某种原因,以下代码仅提供一张图片图像,我希望它打印每张图片、每一个链接和每一个价格,有什么帮助吗? (另外,如果你们知道如何将这些数据放入数据库模型中,这样我就不必总是抓取网站,我全神贯注,但这可能是另一个问题)干杯!

这是模板文件:

{% extends "base.html" %}

{% block title %}Boats{% endblock %}

{% block content %}

<img src="{{ fetch_boats }}"/>

{% endblock %}

这里是views.py文件:

#views.py
from django.shortcuts import render_to_response
from django.template.loader import get_template
from django.template import Context
from django.http import Http404, HttpResponse
from fetch_images import fetch_imagery

def fetch_it(request):
    fi = fetch_imagery()
    return render_to_response('fetch_image.html', {'fetch_boats' : fi})

这里是 fetch_images 模块:

#fetch_images.py
from BeautifulSoup import BeautifulSoup
import re
import urllib2

def fetch_imagery():
    response = urllib2.urlopen("http://www.boattrader.com/search-results/Type")
    html = response.read()

#create a beautiful soup object
    soup = BeautifulSoup(html)

#all boat images have attribute height=165
    images = soup.findAll("img",height="165")
    for image in images:
        return image['src'] #print th url of the image only

# all links to detailed boat information have class lfloat
    links = soup.findAll("a", {"class" : "lfloat"})
    for link in links:
        return link['href']
        #print link.string

# all prices are spans and have the class rfloat
    prices = soup.findAll("span", { "class" : "rfloat" })
    for price in prices:
        return price
        #print price.string

最后,如果需要,urlconf 中的映射 url 如下:

from django.conf.urls.defaults import *
from mysite.views import fetch_it

urlpatterns = patterns('', ('^fetch_image/$', fetch_it))

【问题讨论】:

    标签: python django django-templates screen-scraping django-views


    【解决方案1】:

    您的 fetch_imagery 函数需要一些工作 - 因为您要返回(而不是使用 yield),第一个 return image['src'] 将终止函数调用(我在这里假设所有这些返回都是与您的代码显示的函数定义相同)。

    另外,我的假设是您将从fetch_imagery 返回一个列表/元组(或定义一个生成器方法),在这种情况下,您的模板需要如下所示:

    {% block content %}
        {% for image in fetch_boats %}
            <img src="{{ image }}" />
        {% endfor %}
    {% endblock %}
    

    这基本上将遍历列表中的所有项目(在您的情况下为图片网址),并为每个项目创建img 标签。

    【讨论】:

    【解决方案2】:

    超出范围,但在我看来,报废是过多的 CPU 时间/内存/带宽消耗,我认为应该在后台以异步方式完成。

    这是个好主意 :)

    【讨论】:

    • 超出范围?这是如何异步完成的?我想创建的应用程序需要实时数据,因为它在 kayak.com 中。这是一个异步刮板吗?还在学习*.. 谢谢!
    【解决方案3】:

    我在网上搜索了很长一段时间,寻找展示抓取数据的示例,这篇文章确实很有帮助。自从问题首次发布以来,模块已经发生了一些细微的变化,所以我想我会更新它并发布我拥有的代码以及所需的更改。

    这样做的好处是它提供了一个示例,说明如何运行一些 Python 代码来响应流量,并生成没有任何理由涉及数据库或模型类的简单内容。

    假设您有一个可以添加这些更改的工作 Django 项目,您应该能够浏览到 &lt;your-base-url&gt;/fetch_boats 并看到一堆船图片。

    views.py

    import django.shortcuts
    from django.shortcuts import render
    from bs4 import BeautifulSoup
    import urllib.request
    
    def fetch_boats(request):
        fi = fetch_imagery()
        return render(request, "fetch_boats.html", {"boat_images": fi})
    
    def fetch_imagery():
        response = urllib.request.urlopen("http://www.boattrader.com")
        html     = response.read()
        soup     = BeautifulSoup(html, features="html.parser")
        images   = soup.findAll("img")
    
        for image in images:
            yield image["src"]
    

    urls.py

    from django.urls import path
    from .views import fetch_boats
    
    urlpatterns = [
        path('fetch_boats', fetch_boats, name='fetch_boats'),
    ]
    

    templates/fetch_boats.html

    {% extends 'base.html' %}
    {% block title %} ~~~&lt; Boats &gt;~~~ {% endblock title %}
    {% block content %}
    
        {% for image in boat_images %}
            <br /><br />
            <img src="{{ image }}" />
        {% endfor %}
    
    {% endblock content %}
    

    【讨论】:

      猜你喜欢
      • 2018-02-01
      • 2021-11-17
      • 2022-12-03
      • 2021-04-29
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 2016-03-16
      • 2019-01-20
      相关资源
      最近更新 更多