scrapy学习第八课(代码片段)

helenandyoyo helenandyoyo     2023-02-25     213

关键词:

python爬虫框架scrapy学习第八课

目标爬取文章,实现文本和图片数据存储

文本数据以json文件存储

文本数据存储在mongodb数据库中

图片保存在本地

爬取地址:伯乐在线文章

爬虫实例

1.items.py

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class JobboleItem(scrapy.Item):
    #标题
    title = scrapy.Field()

    #发布日期
    create_date = scrapy.Field()

    #链接
    url = scrapy.Field()

    #MD5加密的url
    url_object_id = scrapy.Field()

    #图片的url
    front_image_url = scrapy.Field()

    #图片存储路径
    front_image_path = scrapy.Field()

    #点赞数
    praise_nums = scrapy.Field()

    #收藏数
    fav_nums = scrapy.Field()

    #评论数
    comment_nums = scrapy.Field()

    #标签
    tag = scrapy.Field()

    #内容
    #content = scrapy.Field()

2.bole.py

# -*- coding: utf-8 -*-
import scrapy
from urllib.parse import urljoin
from jobBole.items import JobboleItem
import re
import hashlib
import datetime

def get_md5(md5str):
    #生成1个MD5对象
    m1 = hashlib.md5()
    #使用MD5对象你的update方法进行md5转换
    m1.update(md5str.encode("utf-8"))
    md5ConvertStr = m1.hexdigest()
    return md5ConvertStr


class BoleSpider(scrapy.Spider):
    name = 'bole'
    allowed_domains = ['blog.jobbole.com']
    start_urls = ['http://blog.jobbole.com/all-posts/']

    def parse(self, response):
        '''
        1.获取文章列表也中具体文章url,并交给scrapy进行下载后并进行解析
        2.获取下一页的url并交给scrapy进行下载,下载完成后,交给parse
        :param response:
        :return:
        '''

        #解析列表页中所有文章的url, 并交给scrapy下载并解析
        post_nodes = response.css("#archive .floated-thumb .post-thumb a")
        for post_node in post_nodes:
            #image_url是图片的地址
            image_url = post_node.css("img::attr(src)").extract_first("")
            post_url = post_node.css("::attr(href)").extract_first("")
            #这里通过meta参数将图片的url传递进来,parse.urljoin的好处是如果有域名,则前面的response.url不生效
            #如果没有,就会把response.url和post_urlz做拼接
            yield scrapy.Request(url=urljoin(response.url, post_url), meta=
                "front_image_url": urljoin(response.url, image_url)
            ,callback = self.parse_detail)  

        #提取下一页并交给scrapy下载
        next_url = response.css(".next.page-numbers::attr(href)").extract_first("")   
        curr_page = int(response.xpath('//span[@class="page-numbers current"]/text()').extract()[0])
        if next_url and curr_page < 3:
            yield scrapy.Request(url = next_url, callback = self.parse)

    def parse_detail(self, response):
        '''
        获取文章的详细内容
        :param response:
        :return:
        '''
        article_item = JobboleItem()
        front_image_url = response.meta.get("front_image_url", "")
        title = response.xpath('//div[@class="entry-header"]/h1/text()').extract_first()
        
        create_date = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/text()').extract()[0].strip().split()[0]
        tag_list = response.xpath('//p[@class="entry-meta-hide-on-mobile"]/a/text()').extract()
        #去掉标签中的评论
        tag_list = [element for element in tag_list if  -1 == element.find("评论")]
        tag = ",".join(tag_list)
        praise_nums = response.xpath('//span[contains(@class, "vote-post-up")]/h10/text()') .extract()[0]
        print('praise_nums  ',  praise_nums)
        if len(praise_nums) == 0:
            praise_nums = 0
        else:
            praise_nums = int(praise_nums[0]) 
       
        fav_nums = response.xpath('//span[contains(@class, "bookmark-btn")]/text()').extract()[0]
        match_re = re.match(".*(\\d+).*", fav_nums)
        if match_re:
            fav_nums = int(match_re.group(1))
        else:
            fav_nums = 0
        #print('@@@@   ', response.xpath('//a[@href="#article-comment"]/span/text()').extract())
        comment_nums = response.xpath('//a[@href="#article-comment"]/span/text()').extract()[0]
    
        match_com = re.match(".*(\\d+).*", comment_nums)
        if match_com:
            comment_nums= int(match_com.group(1))
        else:
            comment_nums = 0

        content = response.xpath('//div[@class="entry"]').extract()[0]

        article_item['url_object_id'] = get_md5(response.url) #对地址进行md5变成了定长
        article_item['title'] = title
        article_item['url'] = response.url
        try:
            create_date = datetime.datetime.strptime(create_date, '%Y/%m/%d').date()
        except Exception as e:
            create_date = datetime.now().date()

        article_item['create_date'] = str(create_date)
        article_item['front_image_url'] = [front_image_url]
        article_item['praise_nums'] = int(praise_nums)
        article_item['fav_nums'] = fav_nums
        article_item['comment_nums'] = comment_nums
        article_item['tag'] = tag
        #article_item['content'] = content
        yield article_item

3.settings.py

ITEM_PIPELINES = 
   'jobBole.pipelines.JobbolePipeline': 300,
   'jobBole.pipelines.ArticleImagePipeline' : 301,
   'jobBole.pipelines.MongoDBTwistedPipline': 302

IMAGES_STORE = 'D:\\SunWork\\python\\jobBole'

MONGODB_HOST = '127.0.0.1'
MONGODB_PORT = 27017
MONGODB_DBNAME = 'bole'
MONGODB_SHEETNAME = 'bolePaper'

4.pipelines.py

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html

import scrapy
from scrapy.pipelines.images import ImagesPipeline
import codecs
import json
import pymongo
from scrapy.conf import settings

class JobbolePipeline(object):
    '''
    返回json数据到文件中
    '''
    def __init__(self):
        self.file = codecs.open("article.json", 'w',encoding='utf-8')

    def process_item(self, item, spider):
        print('@@@@@@@@@@ ', item)
        lines = json.dumps(dict(item), ensure_ascii=False) + "\\n"
        self.file.write(lines)
        return item

    def spider_closed(self, spider):
        self.file.close()

class ArticleImagePipeline(ImagesPipeline):
    '''
    对图片的处理
    '''
    def get_media_requests(self, item, info):
        for image_url in item['front_image_url']:
            yield scrapy.Request(image_url)
        

    def item_completed(self, results, item, info):
        for ok, value in results:
            if ok:
                image_file_path = value['path']
                item['front_image_path'] = image_file_path
            else:
                item['front_image_path'] = ""
           
        return item
    
class MongoDBTwistedPipline(object):
    def __init__(self):
        #主机
        host = settings["MONGODB_HOST"]
        #端口
        port = settings["MONGODB_PORT"]
        #数据库名
        dbname = settings["MONGODB_DBNAME"]
        #数据表名
        sheetname = settings["MONGODB_SHEETNAME"]
        #创建MONGODB数据库
        client = pymongo.MongoClient(host=host, port=port)
        #指定数据库
        mydb = client[dbname]
        #指定数据表
        self.post = mydb[sheetname]
    
    def process_item(self, item, spider):
        data = dict(item)
        self.post.insert(data)
        return item

注:代码来源https://www.cnblogs.com/zhaof/p/7173094.html。在此基础上进行部分修改。

第八课学习做的一个小案例,用来去除底部导航最后一个|(代码片段)

全部代码如下<style>.footwidth:100%;margin:0auto;height:80px;background:#5283ff;#footnavlist-style:none;display:flex;justify-content:center;#footnavlifont-size:18px;padding-top:25px;#footnavliac 查看详情

python第八课异常处理(代码片段)

...起来的时候,这个时候我们就需要用到我们现在需要学习的异常处理,将出现错误的代码暂时进行异常处理。异常捕获可以使用try语句来实现,任何出现在try语句范围的异常都会被及时捕获到。try语 查看详情

python第八课(代码片段)

day08---mongoDB和python的结合使用课堂笔记:1、BeautifulSoup解析库2、MongoDB存储库3、requests-html请求库BeautifulSoup1、什么bs4,为什么要使用bs4?是一个基于re开发的解析库,可以提供一些强大的解析功能。提高提取数据的效率与爬虫开发... 查看详情

第八课使用数据处理函数(代码片段)

8.1函数提取字符串的组成部分Access使用MID();DB2、Oracle、PostgreSQL和SQLite使用SUBSTR();MySQL和SQLServer使用SUBSTRING()数据类型转换Access和Oracle使用多个函数,每种类型的转换有一个函数;DB2和PostgreSQL使用CAST();MariaDB、MySQL和SQLServer使... 查看详情

golang✔️走进go语言✔️第八课函数(代码片段)

【Golang】✔️走进Go语言✔️第八课概述函数函数定义函数传递参数函数传递地址函数闭包概述Golang是一个跨平台的新生编程语言.今天小白就带大家一起携手走进Golang的世界.(第8课)函数函数(Function)是基本的代码的代码块,用于执... 查看详情

golang✔️走进go语言✔️第八课函数(代码片段)

【Golang】✔️走进Go语言✔️第八课概述函数函数定义函数传递参数函数传递地址函数闭包概述Golang是一个跨平台的新生编程语言.今天小白就带大家一起携手走进Golang的世界.(第8课)函数函数(Function)是基本的代码的代码块,用于执... 查看详情

jsp第八课javabean与jsp动作的学习(代码片段)

...处理方法接下来我们通过一个小案例来引导出这一课程要学习的内容,创建一个jsp文件,并存储一个学生的六个数据信息至四大作用域的其中一个:<%@pageimport="com.abc.Student"%><%@pagelanguage="java"contentT... 查看详情

第八课《复杂页面实现》(代码片段)

按照如下设计图进行页面的实现说明:最左侧一列要求自适应浏览器高度,左上面4个按钮相对浏览器左上角固定位置,左下方两个按钮相对浏览器左下角固定位置左侧第二列(蓝色背景色)导航列固定宽度,高度也是自适应浏览器... 查看详情

cs231n第八课:目标检测定位学习记录

结合视频第八集和笔记:http://chuansong.me/n/353443351445本节课程从分类(Classification),定位(Localization)和检测(Detection)三个方面入手。从上图可以直观的看到:1.对于分类而言,就是对于给定的图片把其划分到给定的几种类别... 查看详情

第八课泛型编程简介

...)注:数据结构课程并不关心数据元素的具体类型二、为学习数据结构选择合适的语言1、由于数据结构并不关心具体的数据类型,故支持泛型编程的语言最适合和数据结构课程的学习三、泛型编程的概念1、不考虑具体数据类型... 查看详情

第八课网络通信

unix_c_08.txt================第八课网络通信================一、基本概念------------1.ISO/OSI七层网络协议模型~~~~~~~~~~~~~~~~~~~~~~~~~~+------------+--------------+---|应用层|Application|^+------------+--------------+||表示层|Pr 查看详情

第八天,scrapy的几个小技巧(代码片段)

 一.微博模拟登陆1.百度搜微博开放平台可满足爬取量不大的情况2.微博模拟登陆和下拉鼠标应对ajax加载fromseleniumimportwebdriverimporttimebrowser=webdriver.Chrome()browser.get(‘https://www.weibo.com‘)time.sleep(10)browser.find_element_by_css_se 查看详情

7.8-uc-第八课:网络通信

================第八课 网络通信================一、基本概念------------1.ISO/OSI七层网络协议模型~~~~~~~~~~~~~~~~~~~~~~~~~~+------------+--------------+---| 应用层 | Application| ^+------------+------ 查看详情

第八课

一.定位网页元素  position :    1.static :默认值,代表没有定位,元素没有定位会以标准文档流方式展现出来    2.relative :相对定位,元素以自身原来位置进行定位(如果设置元素浮... 查看详情

12.4日java第八课

instanceof操作符()instanceofC会被编译为方法调用--InstanceofOperator(O,C)InstanceofOperator(O,C){if(typeofC!==‘object‘){throwTypeError;}letinstOfHandler=C[Symbol.hasInstance];if(typeofinstOfHandler!==‘undefined‘){ 查看详情

快学scala第八课(嵌套类)

嵌套类:classHuman{classStudent{valage=10}}objectClassDemo{defmain(args:Array[String]):Unit={valh=newHumanvals=newh.Studentprintln(s.age)}}有时会遇到这种情况:classHuman{classStudent{defaddS(s:Student)={valab=newAr 查看详情

第八课javascript基础1

<scripttype="text/javascript">vara=‘1000‘;a=parseInt(a);alert(a);</script><scripttype="text/javascript">vara=confirm("打游戏吗");alert(a);</script>1<scripttype="text/javascript" 查看详情

重学java基础第八课:硬件和冯洛伊曼系统

  查看详情