轻量级爬虫实例——爬取百度百科1000个页面的数据

轻量级爬虫实例——爬取百度百科1000个页面的数据

爬虫程序baike_spider分为5个模块:
——爬虫总调度程序 (spider_main)
——url管理器 (url_manager)
——网页下载器 (html_downloader)
——网页解析器 ( html_parser)
——将数据处理好的数据写出到 html 的页面 (html_outputer)

爬虫总调度程序(spider_mian):

from baike_spider import url_manager,html_parser,html_downloader,html_outputer  #总调度程序导入其余模块

class SpiderMain(object):          #创建SpiderMain爬虫类
    def __init__(self):            #初始化模块对象
        self.urls = url_manager.UrlManager()     #urlg管理器对象 
        self.downloader = html_downloader.HtmlDownloader()    #网页下载器对象
        self.parser =  html_parser.HtmlParser()    #网页解析对象
        self.outputer = html_outputer.HtmlOutputer()     #网页输出对象
        
    def crawling(self,root_url):      #通过入口页爬取相关词条数据
        count = 1       #爬取页面数量统计量
        self.urls.add_new_url(root_url)             #向待爬取url集合添加入口url
        
        while self,urls.has_new_url():               #循环爬取,条件:待爬取url集合非空
            try:                                     # 可能出现解析出的url无法打开或者内容丢失,进行异常处理
                new_url= self.urls.get_new_url()         #从待爬取的url集合中取出一个url
                print("crawling %d: %s"%(count,new_url)        #打印爬取进度状态信息
                html_cont = self.downloader.download(new_url)    #下载url的html文本
                new_urls,new_data = self.parser.parse(new_url,html_cont)   #解析入口页html文本得出入口页中所有相关url存入new_urls变量
                self.urls.add_new_urls(new_urls)        #new_urls变量中的url加入到待爬取集合中 
                self.outputer.collect_data(new_data)         #收集标题、简介数据存入列表
                
                if count ==1000:   #统计达到 1000退出循环
                    break
                   
                count+=1     #循环一次自加1
            except:
                print("crawling failed")    #爬取失败则打印出错信息crawling failed
                
        self.outputer.output_html()     #将url 标题 简介 输出为html文件
            
if __name = "__mian__":
    root_url = "https://baike.baidu.com/item/Python/407313"     #入口页
    obj_spider = SpiderMain()        #创建爬虫对象 
    obj_spider.crawling(root_url)    #爬取并输出数据

URL管理器模块(url_manager):

class UrlManager(object):       #创建UrlManager类
    def __init__(self):             #初始化待爬取集合和已爬取集合
        self.new_urls = set()       #待爬取集合 
        self.old_urls = set()       #已爬取集合
    def add_new_url(self,url):     #添加新url方法 
        if url is None:            #url为空,返回
            return
        if url not in old_urls and url not in new_urls:    #url都不在待爬取和已爬取集合中,进行添加
            self.new_urls.add(url)       #集合添加为内置add方法
    def add_new_urls(self,urls):          #添加多个url
        if urls is None or len(urls) ==0:    #urls为空或者urls的长度为0
            return
        for url in urls:         #依次添加urls中的url进待爬取集合
            self.add_new_url(url)
    def has_new_url(self):      #待爬取集合非空 返回True
        return len(self.new_urls) != 0 
    def get_new_urls(self):           #取出待爬取集合中的一个url
        new_url = self.new_urls.pop()    #取出
        self.old_urls.add(new_url)       #同时放入已爬取集合
        return new_url          #返回取出的url

网页下载器 (html_downloader)

from urllib2 import request       #导入urllib2包的request模块

class HtmlDownloader(objct):    #创建HtmlDownloader类
    def download(self,url):            #url非空则下载其对应的html文本
        if url is None:
            return None
        request1= request.Request(url)           #初始化request对象 
        request1.add_header("user-agent", "Mozilla/5.0")       #添加请求头,模拟浏览器
        response = request.urlopen(request1)      #打开url对应的html
        if response1.getcode != 200:      #状态为 200,访问成功
            return None
        return respone.read()     #返回html文本

网页解析器 ( html_parser)

from bs4 import BeautifooulSoup         #导入模块
from urllib.parse import urlparse
import re   #urlparse是url解析器 

class HtmlParser(object):          #创建HtmlParser类
    def _get_new_urls(self, page_url, soup):    #解析html文本获取urls的方法
        in_page_urls = set()        
        links = soup.find_all('a', href=re.compile(r"/item/\S+/\d+"))          #找到所有满足的url
  
        for link in links:
            new_url = link['href']
            new_full_url = urljoin(page_url, new_url)      #urljoin可以将基地址与相对地址形成一个绝对地址
             in_page_urls.add(new_full_url)
        return  in_page_urls

    def _get_new_data(self, page_url, soup):     #解析url对应的标题、简介数据
        res_data = {}          #数据字典 
        res_data['url'] = page_url    #键url
        title_node = soup.find('dd', class_="lemmaWgt-lemmaTitle-title").find("h1")   #找出标题
        res_data['title'] = title_node.get_text()       #键title

        summary_node = soup.find('div', class_="lemma-summary")     #找出简介
        res_data['summary'] = summary_node.get_text()        #键summary
        return res_data      #返回url对应的字典 

    def parse(self, page_url, html_cont):       #url为非空或者html为非空时解析
        if page_url is None or html_cont is None:      
            return 
        soup = BeautifulSoup(html_cont, 'html.parse', from_encoding='utf-8')      #解析html文本
        new_urls = self._get_new_urls(page_url, soup)       #得出html中的urls
        new_data = self._get_new_data(page_url, soup)     #得出html中的标题和简介
        return new_urls, new_data       #返回html中的urls和输出数据字典 

网页输出(html_outputer):

class HtmlOutputer(object):      #创建HtmlOutputer类
    def __init__(self):    
        self.datas=[]     #列表
    #收集数据
    def collect_data(self,data):    #数据非空放入列表
        if data is None:
            return
        self.datas.append(data)
        
    def output_html(self):
        fout=open('output.html','w',encoding='utf-8')
        #输出到output.html中,w为写模式,编码为utf-8
        fout.write("<html>")
        fout.write("<body>")
        fout.write("<table>")
        
        #ASCI
        for data in self.datas:     #列表分条写入fout这个html文档
            fout.write("<tr>")
            fout.write("<td>s%</td>" % data['url'])
            fout.write("<td>s%</td>" % data['title'])
            fout.write("<td>s%</td>" % data['summary'])
            fout.write("</tr>")
        
        
        fout.write("</table>")
        fout.write("</body>")
        fout.write("</html>")
        fout.close()      #关闭fout文件

写在最后,欢迎关注一个一起学python的微信公众号:大众学python

掏出手机扫一扫:
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用Python百度图片并保存的示例代码: ```python # 导入依赖库 import requests import re import os # 设置搜索关键字 keyword = "美食" # 设置图片保存路径 save_path = "./images/" # 构造百度图片搜索的URL url = "https://image.baidu.com/search/index?tn=baiduimage&word={}".format(keyword) # 发送HTTP请求并获响应 response = requests.get(url) # 使用正则表达式从响应内容中提图片URL列表 img_urls = re.findall('"objURL":"(.*?)",', response.text, re.S) # 遍历图片URL列表并下载保存图片 for i, img_url in enumerate(img_urls): try: # 发送HTTP请求并获响应 response = requests.get(img_url, timeout=10) # 设置图片保存路径 img_path = os.path.join(save_path, "{}.jpg".format(i)) # 保存图片 with open(img_path, "wb") as f: f.write(response.content) print("成功下载第{:>3d}张图片!".format(i+1)) except Exception as e: print("下载第{:>3d}张图片失败:{}".format(i+1, e)) ``` 解释一下上述代码的主要步骤: 1. 设置搜索关键字和图片保存路径 2. 构造百度图片搜索的URL 3. 发送HTTP请求并获响应 4. 使用正则表达式从响应内容中提图片URL列表 5. 遍历图片URL列表并下载保存图片 需要注意的是,这种方式只是简单的使用正则表达式从响应内容中提图片URL,而没有使用任何API,因此可能存在一些不稳定性和容易被反爬虫机制封禁的风险。建议在使用时注意合理使用代理、设置请求头等防反措施。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值