【新闻推荐系统】(task3)Scrapy基础及新闻爬取实战

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 一、Scrapy的简介与安装python环境的安装:python 环境,使用minicon

一、Scrapy的简介与安装

python环境的安装:

python 环境,使用miniconda搭建,安装miniconda的参考链接:https://blog.csdn.net/pdcfighting/article/details/111503057


在安装完miniconda之后,创建一个新闻推荐的虚拟环境,可以将其命名为news_rec_py3,这个环境将会在整个新闻推荐项目中使用。

conda create -n news_rec_py3 python==3.8

1.0 爬虫工具介绍

需要掌握定向网络数据爬取和网页解析的基本能力。


requests库和scrapy爬虫框架对比:

image.png

相同点:可用性逗号,文档丰富,入门简单,都没有处理js、提交表单、应对验证码等功能(可扩展)。

requests:页面级爬虫,有功能库,并发性考虑不足,重点在于页面下载、定制灵活,上手简单;scrapy:网站级爬虫,是框架,并发性好,重点在于爬虫结构;一般定制灵活,深度定制困难。

非常小的需求可以用requests库;大一点的需求用scrapy框架,定制程度很高的需求用自搭框架。

(1)requests库

get构造一个向服务器请求资源的Requst对象,返回一个包含服务器资源的Response对象。

# -*- coding: utf-8 -*-
"""
Created on Tue Dec 21 09:10:31 2021
@author: 86493
"""
import requests
r=requests.get("http://www.baidu.com")
#检测请求的状态码,200则访问成功
r.status_code 
# 200
#如果没有赋值则显示'ISO-8859-1',显示的不是正常字符
r.encoding='utf-8' 
r.text
type(r)
# requests.models.Response
r.headers #返回访问页面的头部信息
"""
{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 
 'Connection': 'keep-alive', 
 'Content-Encoding': 'gzip', 
 'Content-Type': 'text/html', 
 'Date': 'Tue, 21 Dec 2021 01:10:54 GMT', 
 'Last-Modified': 'Mon, 23 Jan 2017 13:27:56 GMT', 
 'Pragma': 'no-cache', 
 'Server': 'bfe/1.0.8.18', 
 'Set-Cookie': 'BDORZ=27315; 
 max-age=86400; domain=.baidu.com; 
 path=/', 'Transfer-Encoding': 'chunked'}
"""

(2)request爬取网页的通用框架

def getHTMLText(url):
    try:
        r=requests.get(url,timeout=30)
        r.raise_for_status() #如果状态不是200,引发HTTPEroor异常
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return "产生异常"
if __name__=="__main__":
    url="http://www.baidu.com"
    print(getHTMLText(url))

检测请求的状态码为200(表示访问成功,如果是404则失败),爬取后返回http响应内容的字符串形式,即百度url对应的页面内容:

<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

(3)Scrapy框架

Scrapy常用命令:

image.png

Scrapy框架的流程图:


image.png

入口spiders(负责页面解析),出口是item pipelines(负责对提取的信息后处理);

右下角的三个模块已编写好(用户不需编写),中间键download middleware对这三个模块进行用户可配置的控制(用户可修改、丢弃、新增请求或响应);如果用户不需要对request或response进行修改则不需要改中间键。(有两个中间键:spiders和engine之间,engine和downloader之间)

3条主要的数据流即上图中的三条不同颜色的路径。

用户主要编写的模块:


最核心的模块是spider:解析downloader返回的响应(response);产生爬取项(scraped item);产生额外的爬取请求(request)。

item pipelines:

以流水线方式处理spider产生的爬取项;

由一组操作顺序组成,类似流水线,每个操作是一个item pipeline类型;

可能操作:清理、检验和查重爬取项中的HTML数据、将数据存储到数据库中。

1.1 Scrapy安装

Scrapy 是一种快速的高级 web crawling 和 web scraping 框架,用于对网站内容进行爬取,并从其页面提取结构化数据。


Ubuntu下安装Scrapy,需要先安装依赖Linux依赖

sudo apt-get install python3 python3-dev python3-pip libxml2-dev libxslt1-dev zlib1g-dev libffi-dev libssl-dev

在新闻推荐系统虚拟conda环境中安装scrapy

pip install scrapy

1.2 scrapy项目结构

默认情况下,所有scrapy项目的项目结构都是相似的,在指定目录对应的命令行中输入如下命令,就会在当前目录创建一个scrapy项目

scrapy startproject myproject

image.png

项目的目录结构如下:

myproject/
    scrapy.cfg
    myproject/  
        __init__.py
        items.py
        middlewares.py
        pipelines.py
        settings.py
        spiders/
            __init__.py

image.png

scrapy.cfg: 项目配置文件,注意:这里的部署更多的是指将爬放在特定的服务器上,并且在服务器配置好相关的的操作接口,如果是在本机的爬虫,不需要改变部署的配置文件。

myproject/ : 项目python模块, 代码将从这里导入

myproject/ items.py: 项目items文件

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class MyprojectItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass
  • myproject/ pipelines.py: 项目管道文件,将爬取的数据进行持久化存储
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
class MyprojectPipeline:
    def process_item(self, item, spider):
        return item

myproject/ settings.py: 项目配置文件,可以配置数据库等。

myproject/ spiders/: 放置spider的目录,爬虫的具体逻辑就是在这里实现的(具体逻辑写在spider.py文件中),可以使用命令行创建spider,也可以直接在这个文件夹中创建spider相关的py文件。



myproject/ middlewares:中间件,请求和响应都将经过他,可以配置请求头、代理、cookie、会话维持等。

二、scrapy项目结构详解

2.1 spider的抓取周期

spider:定义一个特定站点(或一组站点)如何被抓取的类,包括如何执行抓取(即跟踪链接)以及如何从页面中提取结构化数据(即抓取项)。

spider:为特定站点(或者在某些情况下,一组站点)定义爬行和解析页面的自定义行为的地方。

爬行器是自己定义的类(ps:在spiders文件夹中),Scrapy使用它从一个网站(或一组网站)中抓取信息。它们必须继承 Spider父类 并定义要做出的初始请求,可选的是如何跟随页面中的链接,以及如何解析下载的页面内容以提取数据。


对于spider来说,抓取周期是这样的:


首先生成对第一个URL进行爬网的初始请求,然后指定一个回调函数(该函数使用从这些请求下载的响应进行调用)。要执行的第一个请求是通过调用 start_requests() 方法,该方法(默认情况下)生成 Request 中指定的URL的 start_urls 以及 parse 方法作为请求的回调函数。


在回调函数中,解析响应(网页)并返回 item objects , Request 对象,或这些对象的可迭代。这些请求还将包含一个回调(可能相同),然后由Scrapy下载,然后由指定的回调处理它们的响应。


在回调函数中,解析页面内容,通常使用 选择器,CSS Selector (但也可以使用beautifulsoup、lxml或其他机制)并使用解析的数据生成项。



最后,从spider返回的项目通常被持久化到数据库(在某些 Item Pipeline )或者使用 Feed 导出 .


下面是官网给出的Demo:

import scrapy
class QuotesSpider(scrapy.Spider):
  # 表示一个spider 它在一个项目中必须是唯一的,即不能为不同的spider设置相同的名称。
    name = "quotes" 
    # 必须返回请求的可迭代(您可以返回请求列表或编写生成器函数),spider将从该请求开始爬行。
    # 后续请求将从这些初始请求中相继生成。
    def start_requests(self):
        urls = [
            'http://quotes.toscrape.com/page/1/',
            'http://quotes.toscrape.com/page/2/',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse) # 注意,这里callback调用了下面定义的parse方法
    # 将被调用以处理为每个请求下载的响应的方法。
    # Response参数是 TextResponse 它保存页面内容,并具有进一步有用的方法来处理它。
    def parse(self, response):
        # 下面是直接从response中获取内容,为了更方便的爬取内容,
        # 后面会介绍使用selenium来模拟人用浏览器,
        # 并且使用对应的方法来提取我们想要爬取的内容
        page = response.url.split("/")[-2]
        filename = f'quotes-{page}.html'
        with open(filename, 'wb') as f:
            f.write(response.body)
        self.log(f'Saved file {filename}')

2.2 Xpath语言

XPath 是一门在 XML 文档中查找信息的语言,XPath 可用来在 XML 文档中对元素和属性进行遍历。在爬虫的时候使用xpath来选择我们想要爬取的内容是非常方便的。具体参考Xpath教程。要了解xpath, 需要先了解一下HTML(是用来描述网页的一种语言)。


(1)xpath路径表达式

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。这些路径表达式和我们在常规的电脑文件系统中看到的表达式非常相似。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。


(2)熟悉xpath基本语法

了解如何使用xpath语法选取我们想要的内容,需要熟悉xpath的基本语法。


三、scrapy爬取新闻内容实战

在介绍这个项目之前先说一下这个项目的基本逻辑。


3.1 环境准备:

(1)首先Ubuntu系统里面需要安装好MongoDB数据库,这个可以参考开源项目MongoDB基础

(2)python环境中安装好了scrapy, pymongo包


3.2 项目逻辑:

每天定时从新浪新闻网站上爬取新闻数据存储到mongodb数据库中,并且需要监控每天爬取新闻的状态(比如某天爬取的数据特别少可能是哪里出了问题,需要进行排查)

每天爬取新闻的时候只爬取当天日期的新闻,主要是为了防止相同的新闻重复爬取(当然这个也不能完全避免爬取重复的新闻,爬取新闻之后需要有一些单独的去重的逻辑)

爬虫项目中实现三个核心文件,分别是sina.py(spider),items.py(抽取数据的规范化及字段的定义),pipelines.py(数据写入数据库)

新闻爬取项目和新闻推荐系统是放在一起的,项目的目录结构以及重要文件中的代码实现,最终的项目将会和新闻推荐系统一起开源出来。


image.png

1. 创建一个scrapy项目:

scrapy startproject sinanews

2. 实现item.py逻辑(敲黑板)

sinanews/ items.py: 项目items文件

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class MyprojectItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
from scrapy import Item, Field
# 定义新闻数据的字段
class SinanewsItem(scrapy.Item):
    """
    数据格式化,数据不同字段的定义
    """
    title = Field() # 新闻标题
    ctime = Field() # 新闻发布时间
    url = Field() # 新闻原始url
    raw_key_words = Field() # 新闻关键词(爬取的关键词)
    content = Field() # 新闻的具体内容
    cate = Field() # 新闻类别

3. 实现sina.py (spider)逻辑(敲黑板)

这里需要注意的一点,这里在爬取新闻的时候选择的是一个比较简洁的展示网站进行爬取的,相比直接去最新的新浪新闻观光爬取新闻简单很多,简洁的网站大概的链接:https://news.sina.com.cn/roll/#pageid=153&lid=2509&k=&num=50&page=1

# -*- coding: utf-8 -*-
import re
import json
import random
import scrapy
from scrapy import Request
from ..items import SinanewsItem
from datetime import datetime
class SinaSpider(scrapy.Spider):
    # spider的名字
    name = 'sina_spider'
    def __init__(self, pages=None):
        super(SinaSpider).__init__()
        self.total_pages = int(pages)
        # base_url 对应的是新浪新闻的简洁版页面,方便爬虫,并且不同类别的新闻也很好区分
        self.base_url = 'https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid={}&k=&num=50&page={}&r={}'
        # lid和分类映射字典
        self.cate_dict = {
            "2510":  "国内",
            "2511":  "国际",
            "2669":  "社会",
            "2512":  "体育",
            "2513":  "娱乐",
            "2514":  "军事",
            "2515":  "科技",
            "2516":  "财经",
            "2517":  "股市",
            "2518":  "美股"
        }
    def start_requests(self):
        """返回一个Request迭代器
        """
        # 遍历所有类型的论文
        for cate_id in self.cate_dict.keys():
            for page in range(1, self.total_pages + 1):
                lid = cate_id
                # 这里就是一个随机数,具体含义不是很清楚
                r = random.random()
                # cb_kwargs 是用来往解析函数parse中传递参数的
                yield Request(self.base_url.format(lid, page, r), callback=self.parse, cb_kwargs={"cate_id": lid})
    def parse(self, response, cate_id):
        """解析网页内容,并提取网页中需要的内容
        """
        json_result = json.loads(response.text) # 将请求回来的页面解析成json
        # 提取json中我们想要的字段
        # json使用get方法比直接通过字典的形式获取数据更方便,因为不需要处理异常
        data_list = json_result.get('result').get('data')
        for data in data_list:
            item = SinanewsItem()
            item['cate'] = self.cate_dict[cate_id]
            item['title'] = data.get('title')
            item['url'] = data.get('url')
            item['raw_key_words'] = data.get('keywords')
            # ctime = datetime.fromtimestamp(int(data.get('ctime')))
            # ctime = datetime.strftime(ctime, '%Y-%m-%d %H:%M')
            # 保留的是一个时间戳
            item['ctime'] = data.get('ctime')
            # meta参数传入的是一个字典,在下一层可以将当前层的item进行复制
            yield Request(url=item['url'], callback=self.parse_content, meta={'item': item})
    def parse_content(self, response):
        """解析文章内容
        """
        item = response.meta['item']
        content = ''.join(response.xpath('//*[@id="artibody" or @id="article"]//p/text()').extract())
        content = re.sub(r'\u3000', '', content)
        content = re.sub(r'[ \xa0?]+', ' ', content)
        content = re.sub(r'\s*\n\s*', '\n', content)
        content = re.sub(r'\s*(\s)', r'\1', content)
        content = ''.join([x.strip() for x in content])
        item['content'] = content
        yield item 

4. 数据持久化实现,piplines.py(敲黑板)

这里需要注意的就是实现SinanewsPipeline类的时候,里面很多方法都是固定的,不是随便写的,不同的方法又不同的功能,这个可以参考scrapy官方文档。

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
import time
import datetime
import pymongo
from pymongo.errors import DuplicateKeyError
from sinanews.items import SinanewsItem
from itemadapter import ItemAdapter
# 新闻item持久化
class SinanewsPipeline:
    """
    数据持久化:将数据存放到mongodb中
    """
    def __init__(self, host, port, db_name, collection_name):
        self.host = host
        self.port = port
        self.db_name = db_name
        self.collection_name = collection_name
    @classmethod    
    def from_crawler(cls, crawler):
        """
        自带的方法,这个方法可以重新返回一个新的pipline对象,并且可以调用配置文件中的参数
        """
        return cls(
            host = crawler.settings.get("MONGO_HOST"),
            port = crawler.settings.get("MONGO_PORT"),
            db_name = crawler.settings.get("DB_NAME"),
            # mongodb中数据的集合按照日期存储
            collection_name = crawler.settings.get("COLLECTION_NAME") + \
                "_" + time.strftime("%Y%m%d", time.localtime())
        )
    def open_spider(self, spider):
        """开始爬虫的操作,主要就是链接数据库及对应的集合
        """
        self.client = pymongo.MongoClient(self.host, self.port)
        self.db = self.client[self.db_name]
        self.collection = self.db[self.collection_name]
    def close_spider(self, spider):
        """
        关闭爬虫操作的时候,需要将数据库断开
        """
        self.client.close()
    def process_item(self, item, spider):
        """
        处理每一条数据,注意这里需要将item返回
        注意:判断新闻是否是今天的,每天只保存当天产出的新闻,这样可以增量的添加新的新闻数据源
        """
        if isinstance(item, SinanewsItem):
            try:
                # TODO 物料去重逻辑,根据title进行去重,先读取物料池中的所有物料的title然后进行去重
                cur_time = int(item['ctime'])
                str_today = str(datetime.date.today())
                min_time = int(time.mktime(time.strptime(str_today + " 00:00:00", '%Y-%m-%d %H:%M:%S')))
                max_time = int(time.mktime(time.strptime(str_today + " 23:59:59", '%Y-%m-%d %H:%M:%S')))
                if cur_time > min_time and cur_time <= max_time:
                    self.collection.insert(dict(item))
            except DuplicateKeyError:
                """
                说明有重复
                """
                pass
        return item

5. 配置文件,settings.py

from typing import Collection
import sys 
# sys.path.append("/home/recsys/news_rec_server")
sys.path.append("D:/桌面文件/fun-rec-master/codes/news_recsys/news_rec_server")
from conf.dao_config import mongo_hostname, mongo_port, sina_db_name, sina_collection_name_prefix
BOT_NAME = 'sinanews'
SPIDER_MODULES = ['sinanews.spiders']
NEWSPIDER_MODULE = 'sinanews.spiders'
ROBOTSTXT_OBEY = True
ITEM_PIPELINES = {
   'sinanews.pipelines.SinanewsPipeline': 300,
}
MONGO_HOST = mongo_hostname
MONGO_PORT = mongo_port
SINA_DB_NAME = sina_db_name
COLLECTION_NAME_PRFIX = sina_collection_name_prefix

6. 监控脚本,monitor_news.py

# -*- coding: utf-8 -*-
import sys, time
import pymongo
import scrapy 
from sinanews.settings import MONGO_HOST, MONGO_PORT, DB_NAME, COLLECTION_NAME
if __name__ == "__main__":
    news_num = int(sys.argv[1])
    time_str = time.strftime("%Y%m%d", time.localtime())
    # 实际的collection_name
    collection_name = COLLECTION_NAME + "_" + time_str
    # 链接数据库
    client = pymongo.MongoClient(MONGO_HOST, MONGO_PORT)
    db = client[DB_NAME]
    collection = db[collection_name]
    # 查找当前集合中所有文档的数量
    cur_news_num = collection.count()
    print(cur_news_num)
    if (cur_news_num < news_num):
        print("the news nums of {}_{} collection is less then {}".\
            format(COLLECTION_NAME, time_str, news_num))

7. 运行脚本,run_scrapy_sina.sh

# -*- coding: utf-8 -*-
"""
新闻爬取及监控脚本
"""
# 设置python环境
python="/home/recsys/miniconda3/envs/news_rec_py3/bin/python"
# 新浪新闻网站爬取的页面数量
page="1"
min_news_num="1000" # 每天爬取的新闻数量少于500认为是异常
# 爬取数据
scrapy crawl sina_spider -a pages=${page}  
if [ $? -eq 0 ]; then
    echo "scrapy crawl sina_spider --pages ${page} success."
else   
    echo "scrapy crawl sina_spider --pages ${page} fail."
fi
# 检查今天爬取的数据是否少于min_news_num篇文章,这里也可以配置邮件报警
python monitor_news.py ${min_news_num}
if [ $? -eq 0 ]; then
    echo "run python monitor_news.py success."
else   
    echo "run python monitor_news.py fail."
fi

8. 运行项目命令

sh run_scrapy_sina.sh

如果是在命令行打命令,最终查看数据库中的数据:image.png

我在datagrip中的命令:

show dbs;
use SinaNews;
show collections;

我们将数据存入mongodb数据库内,显示当前的集合collections:

image.png

显示2条爬取的新闻:


image.png

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
6月前
|
数据采集 搜索推荐 算法
实战基于矩阵分解的推荐系统
实战基于矩阵分解的推荐系统
|
6月前
|
存储 前端开发 机器人
Python网络数据抓取(6):Scrapy 实战
Python网络数据抓取(6):Scrapy 实战
62 2
|
6月前
|
数据采集 中间件 Python
Scrapy爬虫:利用代理服务器爬取热门网站数据
Scrapy爬虫:利用代理服务器爬取热门网站数据
|
3月前
|
存储 数据采集 中间件
scrapy实战2586个小姐姐带回家
scrapy实战2586个小姐姐带回家
46 3
scrapy实战2586个小姐姐带回家
|
4月前
|
数据采集 存储 缓存
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
使用Scrapy进行网络爬取时的缓存策略与User-Agent管理
|
5月前
|
Web App开发 iOS开发 Python
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
经验大分享:scrapy框架爬取糗妹妹网站qiumeimei.com图片
36 0
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【阿旭机器学习实战】【37】电影推荐系统---基于矩阵分解
【阿旭机器学习实战】【37】电影推荐系统---基于矩阵分解
|
XML 数据采集 JSON
scrapy_selenium爬取Ajax、JSON、XML网页:豆瓣电影
在网络爬虫的开发过程中,我们经常会遇到一些动态加载的网页,它们的数据不是直接嵌入在HTML中,而是通过Ajax、JSON、XML等方式异步获取的。这些网页对于传统的scrapy爬虫来说,是很难直接解析的。那么,我们该如何使用scrapy_selenium来爬取这些数据格式的网页呢?本文将为你介绍scrapy_selenium的基本原理和使用方法,并给出一个实际的案例。
107 0
|
6月前
|
数据采集 JavaScript 开发者
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
使用Scrapy有效爬取某书广告详细过程
|
6月前
|
数据采集 Python
Scrapy框架 -- 深度爬取并持久化保存图片
Scrapy框架 -- 深度爬取并持久化保存图片
122 0