【问题标题】:Get Web Bot To Properly Crawl All Pages Of A Site让 Web Bot 正确抓取网站的所有页面
【发布时间】:2015-04-29 16:52:12
【问题描述】:

我正在尝试爬取网站的所有页面并提取某个标签/类的所有实例。

它似乎一遍又一遍地从同一页面提取信息,但我不知道为什么,因为 len(urls) #The stack of URL's being scraped 有一个钟形曲线变化,这让我觉得我至少在爬行通过链接,但我可能不正确地提取/打印信息。

import urllib
import urlparse
import re
from bs4 import BeautifulSoup

url = "http://weedmaps.com"

如果我尝试仅使用基本的 weedmaps.com URL,则不会打印任何内容,但如果我从一个页面开始,该页面具有我正在寻找的数据类型...url = "https://weedmaps.com/dispensaries/shakeandbake",那么它会提取信息,但它会一遍又一遍地打印相同的信息。

urls = [url] # Stack of urls to scrape
visited = [url] # Record of scraped urls
htmltext = urllib.urlopen(urls[0]).read()

# While stack of urls is greater than 0, keep scraping for links
while len(urls) > 0:
    try:
        htmltext = urllib.urlopen(urls[0]).read()

# Except for visited urls
    except:
        print urls[0]  

# Get and Print Information
    soup = BeautifulSoup(htmltext)
    urls.pop(0) 
    info = soup.findAll("div", {"class":"story-heading"})

    print info

# Number of URLs in stack
    print len(urls)

# Append Incomplete Tags    
    for tag in soup.findAll('a',href=True):
        tag['href'] = urlparse.urljoin(url,tag['href'])
        if url in tag['href'] and tag['href'] not in visited:
            urls.append(tag['href'])
            visited.append(tag['href'])

【问题讨论】:

  • 你能分享一个实际的网站链接吗?
  • 刚刚编辑了问题和 URL。希望这有助于更好地理解它。

标签: python web-scraping web-crawler beautifulsoup


【解决方案1】:

您当前代码的问题是您放入队列的 URL (urls) 指向同一个页面,但指向不同的锚点,例如:

换句话说,tag['href'] not in visited 条件不会过滤指向同一页面但指向不同锚点的不同 URL。

据我所知,您正在重新发明网络抓取框架。但是已经有一种方法可以节省您的时间,使您的网络抓取代码有条理和干净,并且比您当前的解决方案要快得多 - Scrapy

您需要CrawlSpider,配置rules 以跟随链接,例如:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor

class MachineSpider(CrawlSpider):
    name = 'weedmaps'
    allowed_domains = ['weedmaps.com']
    start_urls = ['https://weedmaps.com/dispensaries/shakeandbake']

    rules = [
        Rule(LinkExtractor(allow=r'/dispensaries/'), callback='parse_hours')
    ]

    def parse_hours(self, response):
        print response.url

        for hours in response.css('span[itemid="#store"] div.row.hours-row div.col-md-9'):
            print hours.xpath('text()').extract()

您的回调应该返回或产生Item 实例而不是打印,您可以稍后将其保存到文件、数据库或管道中以不同方式处理。

【讨论】:

  • @Teldridge11 好吧,这是一个单独的问题,但我会先阅读 Scrapy 教程以了解 Scrapy 的工作原理以及关键组件是什么。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 2020-04-02
  • 2020-04-25
  • 1970-01-01
  • 2022-11-02
  • 2016-07-16
  • 1970-01-01
相关资源
最近更新 更多