python爬虫,站长之家

主要目标

爬取下图信息,上图更简单直观。
这里写图片描述

分析思路

首先找到我们要得数据在那,我们先去站长之家去看看;站长之家
这里写图片描述

这里的“全部行业”就是我们要得一级分类,我们来研究一下他的html源代码,
这里写图片描述

然后随意点开一分类看看
这里写图片描述

html源码如下:
这里写图片描述

在点进去一个,我们就看到我们要得数据在哪里了;
这里写图片描述

html内容如下:
这里写图片描述
我们看了这么多的东西有什么用呢?我总结出每级分类的url都可以在html源码里找的到,无须js,ajax等异步加载,那接下来我们看看如何分页的呢?
这里写图片描述
看到这张图我就知道这个二级分类下边有多少页内容了,但是为了保险起见,你们可以点到96页去验证,总页数得到了,我们来研究它如何分页的
这是首页url:http://top.chinaz.com/hangye/index_yule_youxi.html
这是第二页url:http://top.chinaz.com/hangye/index_yule_youxi_2.html
这是最后一页的url:http://top.chinaz.com/hangye/index_yule_youxi_96.html
因此我们可以构造“list” url,首页url唯一,不可构造
那么现在得到的结果就是这是一个很简单的list页爬取,无需处理异步,我们就来考虑要使用什么工具来抓取我们的数据了,由于这是一个很简单的应用,我们就用python2.7.12的urllib2库来抓取

代码如下:

#! -*- coding:utf-8 -*-
# __author__: andy

import random
import urllib2
import re
from time import sleep
import pymongo
from bs4 import BeautifulSoup
from agents.user_agents import agents
from filter import BloomFilter


class HangYe(object):
    def __init__(self):
        # 根url
        self.root_url = "http://top.chinaz.com/hangye/"
        # 实例化一个连接redis的包装类,有去重,此例未用去重
        filter = BloomFilter()
        self.rconn = filter.server
        # 连接mongo库
        client = pymongo.MongoClient("10.4.252.60", 27017)
        # 如果mongo中有这个库就连接这个库,没有就创建这个库
        db = client["hangye"]
        # 创建表,原理同上
        self.shop = db['chinaz']


    def change_agents(self):
        """
        设置use_agent,防止被墙,我这里有一个use_agents池,每次请求时随机从池取出一个添加到请求头里
        :return:
        """
        agent = random.choice(agents)
        return agent

    def base_request(self, url, flag):
        """
        一个基本方法,传入url和一个标识符,每次请求时调用即可,
        :param url:请求的url
        :param flag:返回参数的标识符,为1时返回一级分类和它的url,为None时返回html内容
        :return:
        """
        request = urllib2.Request(url)
        opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
        # 设置设置use_agent,这里也可以设置其他header信息以json格式
        opener.add_headers = [self.change_agents()]
        response = opener.open(request).read()
        # 这里使用BeautifulSoup来树化html,你们也可以用lxml,lxml速度快一点,因为etree是c写的
        soup = BeautifulSoup(response, "lxml")
        if flag == 1:
            all_href = soup.find_all("div", class_="HeadFilter")[0].find_all("a")
            top_list = []
            for top_Category in all_href:
                top_href = top_Category['href']
                text_href = top_Category.get_text(strip=True)
                top_list.append(top_href + "--" + text_href)
            return top_list
        if flag == None:
            return soup

    def top_category(self):
        """
        此函数为了获取,二级分类和它的url,并和一级分类一起存入redis
        :return:
        """
        top_list = self.base_request(self.root_url, 1)
        for hangye in top_list:
            top_msg = hangye.split("--")
            top_url = self.root_url + top_msg[0]
            levels = self.base_request(top_url, 1)
            for levels_msg in levels:
                l = levels_msg.split("--")
                line = l[0] + "--" + l[1] + "--" + top_msg[1]
                print line
                # 存数据
                self.rconn.lpush("hangye:crawl", line)

    def get_web_host(self):
        # 取数据
        msg = self.rconn.lpop("hangye:crawl")
        top_msg = msg.split("--")
        href_url = top_msg[0]
        # 构造 请求url
        levels_url = self.root_url + href_url
        html = self.base_request(levels_url, None)
        len = html.find_all("div", class_="ListPageWrap")[0].find_all("a")
        # 抓取此二级分类下有多少页信息
        len_page = re.findall(r"\d+", len[-2].get_text(strip=True))[0]
        l = 1
        while l <= int(len_page):
            # 判断是否是第一页,已经请求过就直接分析
            if l == 1:
                html_msg = html
            else:
                index_url = href_url.split(".")[0] + "_" + str(l) + ".html"
                levels_url = self.root_url + index_url
                print levels_url
                # 请求数据,并设置flag
                html_msg = self.base_request(levels_url, None)
            web_host = html_msg.find_all("ul", class_="listCentent")[0].find_all("h3", class_="rightTxtHead")
            Chinaz = {}
            Chinaz['top_category'] = top_msg[2]
            Chinaz['level_category'] = top_msg[1]
            for hd in web_host:
                web_name = hd.find_all("a")[0].get_text(strip=True)
                domain = hd.find_all("span")[0].get_text(strip=True)
                Chinaz['web_name'] = web_name
                Chinaz['domain'] = domain
                # 抓取结果存入mongo
                if Chinaz:
                    self.shop.insert(Chinaz, manipulate=False)
            # 将抓取过的url存入redis,方便统计。
            self.rconn.lpush("hangye:success", levels_url)
            print levels_url + "|||" + "Request Successlly !!!"
            l += 1

try:
   hang = HangYe()
   hang.top_category()
   # 读取待爬队列中有多少url
   len = hang.rconn.llen("hangye:crawl")
   while len > 0:
       sleep(1)
       hang.get_web_host()
       len = len -1
   # 读取总共抓取了多少url
   success = hang.rconn.llen("hangye:success")
   print "Crawl success Total %s pages" % success
except (KeyboardInterrupt, SystemExit):
    print "程序意外终止"

代码该讲的已经写在注释里了,我就不罗嗦了;我们就让它跑起来吧!
这里写图片描述

大概不到半个小时就跑完了,这是跑下来的总数据
这里写图片描述

这里是我的github地址,代码随便写的,如有失误请多多指教!!!
有时间会继续更新爬虫的,如异步加载的处理,phantomjs和selenium的使用,scrapy + splash以及scrapy大型集群的搭建和使用,欢迎大家来指正和谈论。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值