8小时带你快速入门爬虫!

python爬虫代码-23个Python爬虫开源项目代码 今天为大家整理了23个Python爬虫项目。整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心。所有链接指向GitHub,祝大家玩的愉快1、WechatSogou [1]– 微信公众号爬虫。基于搜狗微信搜索的微信公众号爬虫接口,可以扩展成基于搜狗搜索的爬虫,返回结果是列表,每一项均是公众号具体信息字典。2、DouBanSpider [2]– 豆瓣读书爬虫。可以爬下豆瓣读书标签下的所有... 阅读详情

爬虫—8小时入门版

# =============================================
# Attribution : Changsha Test Department
# Time        : 2024/3/5
# Author      : UncleP
# =============================================


详细讲解 Requests 和 httpx 库的使用,并以爬取 deepin 论坛数据为例,讲解爬虫框架 Scrapy 的使用方法。

一、Requests

1、简介

Requests 是 Python 最久负盛名的 HTTP 库,没有之一;K 神(Kenneth Reitz)的 for humans 系列中最有名的一个;

K 神帅照

做爬虫、数据分析、接口自动化会经常用到它,非常多有名的 Python 库依赖于 Requests 提供基础能力,比如:httpx(支持异步的 HTTP 库)、locust(性能[负载]测试框架)、HttpRunner(接口自动化框架)等等,都是基于 Requests 构建起来的。

有人甚至建议将 Requests 库合入 Python 标准库发布。只要你想做 HTTP 请求,你肯定会想到 Requests。

Requests 特点:简单、简洁、优雅。

2、安装

系统环境:deepin

pip3 install requests


3、请求

3.1、导入
import requests


所有的功能都在 requests 这个名称空间下。

3.2、GET 请求
r = requests.get("https://www.baidu.com")
print(r.status_code)
print(r.text)


终端打印:

200
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equ ...... # 省略


3.3、POST 请求

https://httpbin.org 是 K 神的一个简单的 HTTP 服务,主要用于试用 requests 里面的一些功能,方便理解;

r = requests.post('https://httpbin.org/post', data={'key': 'value'})
print(r.status_code)
print(r.text)


终端打印:

200
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key": "value"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "9", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-642aa9b9-259b189c1acb1e114a5d6bc7"
  }, 
  "json": null, 
  "origin": "110.191.179.216", 
  "url": "https://httpbin.org/post"
}


3.4、其他请求

其他请求方式不常用,如下:

r = requests.put('https://httpbin.org/put', data={'key': 'value'})
r = requests.delete('https://httpbin.org/delete')
r = requests.head('https://httpbin.org/get')
r = requests.options('https://httpbin.org/get')


3.5、请求头(headers)

请求头通常会加 UA(user agent),这个主要是模仿浏览器的行为,比如模仿使用 Firefox 浏览器:

headers = {
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0"
}

requests.get(url, headers=headers)
requests.post(url, headers=headers)


3.6、参数

(1) get 请求参数

get 请求的参数可以直接在url后面加参数,url?key1=value1&key2=value2,即 url 后面加问号,然后紧接着多个参数的键和值,多个键值之间用 & 符号链接;

这种方式简单是简单,但是参数多了之后,url 会变得很长,看起来胀眼睛,为了更好的可读性,requests 支持这样传递 get 请求的参数:

params = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('https://httpbin.org/get', params=params)


通过打印 r.url 你会发现,实际上也是给你转换成了前面那种 & 连接的方式;

(2)post 请求参数

post 请求参数一般是通过data参数传递,通常 data 是一个字典形式:

data = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('https://httpbin.org/post', data=data)
print(r.text)


执行后终端输出:

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key1": "value1", 
    "key2": "value2"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "23", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-642e7884-7f20428d523e7fda1da61f1a"
  }, 
  "json": null, 
  "origin": "110.191.179.216", 
  "url": "https://httpbin.org/post"
}


如果你拿到的参数,是一个 json 格式,可以直接传递给 json 参数:

jsons = '{"key1": "value1", "key2": "value2"}'
r = requests.post('https://httpbin.org/post', json=jsons)
print(r.text)


执行后终端输出:

{
  "args": {}, 
  "data": "\"{\\\"key1\\\": \\\"value1\\\", \\\"key2\\\": \\\"value2\\\"}\"", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "46", 
    "Content-Type": "application/json", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.28.1", 
    "X-Amzn-Trace-Id": "Root=1-642e79d4-1f0aeb1370ea94cf2c858f9d"
  }, 
  "json": "{\"key1\": \"value1\", \"key2\": \"value2\"}", 
  "origin": "110.191.179.216", 
  "url": "https://httpbin.org/post"
}


4、响应

其实前面的例子已经有体现一点响应了;

r = requests.post('https://httpbin.org/post', data={'key': 'value'})


r 为返回值的对象(Response),通常在项目中我一般用 rsp 来表示(后面的 rsp 和 r 是一个意思,都是表示返回值的对象);

rsp 既然是对象,那来看下对象的方法和属性,咱们 Debug 跑一下就很清楚:

rsp的方法和属性

接下来讲几个比较常用的属性和方法;

4.1、响应内容
r.text


前面例子已经打印过,这里就不打印了;

text 的解码是自动的,大多数情况下都能正常解码;

可以通过 encoding 来查看或修改编码方式:

print(r.encoding)
r.encoding = 'ISO-8859-1'


修改编码方式之后,再使用 r.text 就会以新的编码方式解码。

如果你发现返回的内容编码不对,你可以尝试修改不同的编码,这是个经验积累的过程。

4.2、二进制响应内容

非文本类请求,一般返回的是二进制内容,此时我们应该使用 content 方法:

r.content


将二进制文件保存下来,比如请求返回一个 mp3 文件:

with open("my.mp3", "wb") as f:
    f.write(r.content)


4.3、JSON响应内容

一些 RESTful API 返回通常是 json 内容,我们可以直接使用:

r.json()


获取的类型为 Python 的字典类型;

如果响应包含无效JSON,会抛 requests.exceptions.JSONDecodeError 异常。

5、高阶用法

5.1、Session

Session 对象可以在一次会话中可以有效的处理 cookie 持久化的问题;

s = requests.Session()
# 设置一个cookie为123456789
s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
# 请求一下
r = s.get('https://httpbin.org/cookies')
print(r.text)


执行后终端输出:

{
  "cookies": {
    "sessioncookie": "123456789"
  }
}


5.2、Request

无论是前面讲到的 GET 、 POST 等请求方法:

requests.get()
requests.post()


其底层都是通过调用 Request 这个类来实现的:

class Request():
    def __init__(
        self,
        method=None,
        url=None,
        headers=None,
        files=None,
        data=None,
        params=None,
        auth=None,
        cookies=None,
        hooks=None,
        json=None,
    ):
        pass


因此我们当然可以直接跨过这一步,不让中间商赚差价,直接用 Request:

frome requests import Request
r = Request("GET", url, headers=headers)
r = Request("POST", url, headers=headers)


还没完,记得调用一下 prepare() 方法,然后使用 Session 里面的 send 方法:

举例:

from  requests import Session, Request
s = Session()
r = Request("GET", 'https://httpbin.org/get')
prepped = r.prepare()
resp = s.send(prepped)
print(resp.text)


执行终端输出:

{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Host": "httpbin.org", 
    "User-Agent": "python-urllib3/1.26.13", 
    "X-Amzn-Trace-Id": "Root=1-642e84e2-1328a0210e2252741f20c648"
  }, 
  "origin": "110.191.179.216", 
  "url": "https://httpbin.org/get"
}


二、httpx

1、简介

虽然 Requests 基本已经可以解决大部分问题,但仍然有少部分问题无法解决,比如:HTTP/2(Requests 只支持HTTP/1.1)、异步请求等,这就需要用到 httpx;

httpx 号称下一代 HTTP 客户端,最开始是为了解决 Requests 不支持异步请求的问题,工程名称就叫:requests-async,后面整体迁移到 httpx 仓库中。

由于 httpx 从一开始就是基于 Requests 来搞的,所以它提供的接口几乎和 Requests 保持一致,这对于我们使用来说就简单多了。

2、安装

系统环境:deepin

pip3 install httpx


它还提供命令行工具:

pip3 install 'httpx[cli]'


我一般不咋习惯用命令行做接口请求,所以基本都不装这玩意儿。

3、简单的例子

前面说了 httpx 和 Requests 提供的接口几乎一致,咱们就用 Requests 教程里面的例子;

3.1、GET请求
import httpx

r = httpx.get("https://www.baidu.com")
print(r.status_code)
print(r.text)


执行后终端输出:

200
<html>
<head>
        <script>
                location.replace(location.href.replace("https://","http://"));
        </script>
</head>
<body>
        <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>
</body>
</html>


3.2、POST请求
import httpx

r = httpx.post('https://httpbin.org/post', data={'key': 'value'})
print(r.status_code)
print(r.text)


执行后终端输出:

200
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "key": "value"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "9", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-httpx/0.23.3", 
    "X-Amzn-Trace-Id": "Root=1-642f820c-019ccf8938faee564386038e"
  }, 
  "json": null, 
  "origin": "110.191.179.216", 
  "url": "https://httpbin.org/post"
}


你看,简直是一毛一样。

行啦,都一样咱们就不聊了,后面重点讲讲不一样的。

4、异步请求

异步是一种并发方式,也就是通常说的“协程”,比多线程效率高很多;

httpx 的异步请求主要依赖于标准库 asyncio,使用 async 和 await 关键词;

import asyncio
import httpx

async def my_get():
    async with httpx.AsyncClient() as client:
        r = await client.get("https://www.baidu.com")
        print(r.text)

if __name__ == '__main__':
    asyncio.run(my_get())


client 对象你可以理解为 Requests 里面的 Session 对象。

5、HTTP/2

老实讲 HTTP/2 的网站我还没机会爬过,所以我这里还不太好找例子;

如果你在不小心遇到了也别慌,只需要加一个参数就好了;

import asyncio
import httpx

async def my_get():
    async with httpx.AsyncClient(http2=True) as client:
        r = await client.get("https://www.xxxxxx.com")
        print(r.text)

if __name__ == '__main__':
    asyncio.run(my_get())


在 httpx.AsyncClient() 里面,默认参数:

class AsyncClient:
    def __init__(
        self,
		...
        http1: bool = True,
        http2: bool = False,
		...
    ):
        pass  # 省略其他源码


也就是说默认是开启的 http1,所以只需要在实例化 client 对象的时候,传入参数 http2=True 即可;

三、Scrapy

1、简介

Scrapy 是现阶段 Python 社区最流行的爬虫框架,它能够极大的简化爬虫的编写难度,简化代码。

当然它不是 Python 社区唯一的爬虫框架,但我认为是现阶段最好用的爬虫框架。

经常用同学问,为啥要用 Scrapy,我用 requests 不可以吗?

我觉得这样解释:

  • 不是一个类型

requests 最多算是爬虫工具,不同的人写出来的爬虫代码都不同,重复代码还多,而且对于一些高级的应用场景,如:多线程处理、异步处理、持久化等,估计没几个人能处理的很完美,最后爬下来的数据还要找一堆工具来解析处理,比如:re、BeautifulSoup、lxml等,属实让人挠头;

而爬虫框架通常提供了简单的配置,使用很少的代码就能实现复杂的功能,代码量少了,而且底层也为你处理了很对问题,框架在解析数据也有自带的方案,所以你只需要按照框架所定义好的规范,就可以轻松完成各种任务;

  • 不是一个圈子

Scrapy 主要用于数据爬取,所以说它是爬虫框架,你说用它来做一些 POST 请求发个数据啥的,咱们貌似没这么用过;

而 requests 只要是网络接口请求都能用,爬数据也可以,但你要说爬数据有多强呢,就要看使用的人有多强了;

总结:

  • 新手、老司机做小任务,用哪个都无所谓,用框架的话会轻松很多;
  • 新手做大任务,用框架,不要想,省时省力;
  • 老司机做大任务,用工具可以做,就是有点麻烦;用框架也能搞,但是不能秀出你的实力;

2、安装

系统环境:deepin

pip3 install Scrapy


3、创建项目

咱们就爬取 deepin 论坛的贴子,找找感觉;

创建一个爬虫项目名为:deepin_bbs_spider

cd ~
scrapy startproject deepin_bbs_spider


工程目录结构:

deepin_bbs_spider
├── deepin_bbs_spider
│   ├── __init__.py
│   ├── items.py  # 数据类型定义
│   ├── middlewares.py  # 中间件
│   ├── pipelines.py  # 数据管道
│   ├── settings.py  # 配置项
│   └── spiders  # 放爬虫脚本的目录
│       └── __init__.py
└── scrapy.cfg  # 部署配置文件


4、开始写爬虫

在 ~/deepin_bbs_spider/deepin_bbs_spider/spiders 目录下写我们的爬虫脚本文件,创建一个爬虫,目标是爬取论坛里面帖子内容:

# bbs_spider.py

import scrapy

class BbsSpiderSpider(scrapy.Spider):
    name = "bbs_spider"
    allowed_domains = ["bbs.deepin.org"]
    start_urls = ["https://bbs.deepin.org/?offset=0&limit=20&order=updated_at&where=&languages=zh_CN#comment_title"]

    def parse(self, response):
        post_items = response.css("app-main-pc > div > div:nth-child(3) > app-post-pc")
        for post_item in post_items:
            url = post_item.css("a.post_lin_pc::attr(href)").get()
            title = post_item.css("span.ng-star-inserted::text").getall()
            print("url:", url)
            print("title", title)


啥也不说,先跑起来试试:

cd ~/deepin_bbs_spider
scrapy crawl bbs_spider


跑完之后,终端就会有输出爬取到的帖子信息:

爬取数据展示

你先别管其他的,至少咱们能爬到数据了,接下来咱们慢慢介绍上面这些代码是怎么来的~;

5、逻辑讲解

5.1、生成爬虫模板

看了上面的示例,有同学肯定要问,你咋知道要写个类呢,你咋知道要写个 parse 函数呢?

我确实不知道,scrapy 也知道咱们不知道,所以做了个工具自动生成:

scrapy genspider <spider name> <spider url>


用子命令 genspider,后面加爬虫的名称(spider name),再加要爬取地址(url),就可以在 spiders 目录下自动生成一个 py 文件;

比如,咱们像这样:

scrapy genspider bbs_spider "https://bbs.deepin.org"


执行之后就会自动生成 py 文件:

import scrapy

class BbsSpiderSpider(scrapy.Spider):
    name = "bbs_spider"
    allowed_domains = ["bbs.deepin.org"]
    start_urls = ["https://bbs.deepin.org"]

    def parse(self, response):
		pass


简单讲解一下:

  • 爬虫类是要继承 scrapy.Spider 的,这个不要去动,知道继承就对了;
  • 类变量 name 是爬虫的名称,这玩意儿就是个代号,你想改成王大锤都行,一般赖得去管;
  • 类变量 allowed_domains 爬虫域名;
  • 类变量 start_urls 爬虫目标地址,可以给多个;
  • 实例方法 parse(self, response) 也是固定写法,函数名称最好不动,参数名称不能改,因为是 scrapy 返回的一个 Selector 对象;

这里面核心逻辑就是在 parse 函数里面去写,你可以理解成 response 就是返回的页面信息,你只需要在这里面去提取想要的数据就好了;

response 提供一些方法,能够很方便的进行页面信息提取;

5.2、爬虫编写方法

前面说到爬虫脚本里面 response,它是我们编写代码的核心,所有的数据提取都从这里来;

下面我们讲讲数据的提取方法,这里多嘴一句,我默认大家都是有一点前端基础的,不然下面部分内容可能需要去学习下 html、css相关知识;

首先来讲 css 提取方法,css 的解析是非常灵活的,先用 F12 看下 html 源码:

html 源码

可以看到所有的帖子都在 app-post-pc 标签下面,咱们可以这样写:

def parse(self, response):
    post_items = response.css("app-post-pc")


如果你是使用右键复制的选择器,可能是一个很长的表达式,不太优雅也不利于维护,我个人不太建议使用直接复制表达式,而应该通过观察自己写;

这样的话,post_items 就获取到了所有帖子的 app-post-pc 标签,再看下 app-post-pc 标签下都有啥:

帖子标题

可以看到在 app-post-pc 标签下还有 a 标签,保存了帖子的详情地址(post_url),然后在 a 标签下的 span 标签保存了帖子的类型和标题(title),因此咱们想办法把这两个拿到:

def parse(self, response):
    post_items = response.css("app-post-pc")
    for post_item in post_items:
        url = post_item.css("a.post_lin_pc::attr(href)").get()
        title = post_item.css("span.ng-star-inserted::text").getall()
        print("url:", url)
        print("title", title)


先用 for 循环把 post_items 里面每个 Selector 对象里面的 url 和 title 拿到;

post_item 就是单个的 Selector 对象,我们在它的基础上再通过 css 方法获取到我们想要的数据;(也可以使用 Xpath 技术获取)

  • url 是在 a 标签里面的 href 属性里面,因此:
post_item.css("a.post_lin_pc::attr(href)").get()


表达式里面的 ::attr(href) 这部分是 Scrapy 特有的,:: 表示取值,attr(href) 表示通过 href 属性取值;

get() 方法表示取第一个值,getall() 方法表示取所有的值;(也兼容老版本的 extract_first() 和 extract() 方法,意思是对应一样的,不过明显get() 这种可读性更好更易于理解。)

  • title 在 span 标签里面:
post_item.css("span.ng-star-inserted::text").getall()


text 也是 Scrapy 特有的,表示把标签的文本取出来;

非常好理解对吧,只要你稍微有点前端知识,就能够轻松把表达式写出来;

5.3、获取数据

前面例子是将获取到的数据打印出来,实际业务里面我们肯定是需要将数据保存下来的;

首先我们在 items.py 里面定义数据类型:

# items.py

import scrapy

class DeepinBbsSpiderItem(scrapy.Item):
    # define the fields for your item here like:
    url = scrapy.Field()
    title = scrapy.Field()


写法非常简单,统一使用 scrapy.Field() 来定义就行了;

然后,回到爬虫脚本里面:

import scrapy
from deepin_bbs_spider.items import DeepinBbsSpiderItem

class BbsSpiderSpider(scrapy.Spider):
    ... # 省略部分代码

    def parse(self, response):
        item = DeepinBbsSpiderItem()
        post_items = response.css("app-post-pc")
        for post_item in post_items:
            item["url"] = post_item.css("a.post_lin_pc::attr(href)").get()
            item["title"] = post_item.css("span.ng-star-inserted::text").getall()
            yield item


将 items.py 里面的 DeepinBbsSpiderItem 导进来,实例化一个对象,然后将获取到的数据复制给这个对象,使用 item["url"] 这种给字典添加的方式,注意要和 items.py 里面定义的字段名称保持一致;

最后,使用 yield 将数据返回出来就行了;

将数据写入到 csv 文件里面:

scrapy crawl bbs_spider -o bbs.csv


-o 表示导出数据,执行后,查看 bbs.csv 文件:

csv 文件

这样就将爬取到的数据保存到了一个 csv 文件;

5.4、处理数据

在爬虫脚本里面获取到原始数据之后,我们还有可能会拿数据做进一步处理,比如还想写入数据库、写入 Excel等等;

这些进一步的操作,我们通常是在数据管道 pipelines.py 里面来处理:

class DeepinBbsSpiderPipeline:
    def process_item(self, item, spider):
        return item


这里的 item 就是每一条数据;

比如,你想写入 MySQL数据库(首先要确保数据库表、字段等正常):

import pymysql

class DeepinBbsSpiderPipeline:

    def __init__(self):
        # 在构造函数里面创建数据库连接和游标
    
    def open_spider(self, spider):
        # open_spider 是这个管道开始时要执行的;这里可以不要
    
    def close_spider(self, spider):
        # close_spider 写入关闭数据库的代码
    
    def process_item(self, item, spider):
        # 在这里做写入数据库的动作
        return item 


在上面注释里面写了写入数据库的编写逻辑,由于我们主要想讲解数据管道的操作逻辑,数据库的代码数据基本操作,就不做详细代码示例了,往上搜 pymysql 的使用很多,按照注释的逻辑,对号入座就行了;

如果想写入 Excel 表格逻辑是一样的,也可以表格和数据库同时写入,在 pipelines.py 里面再定义一个管道类就行了;

注意,数据管道逻辑写完之后,要在 settings.py 里面修改配置:

ITEM_PIPELINES = {
    "deepin_bbs_spider.pipelines.DeepinBbsSpiderPipeline": 300,
    # "deepin_bbs_spider.pipelines.XxxxPipeline": 2,
}


ITEM_PIPELINES 是一个字典,key 是数据管道,value 是一个数字;

value 主要用于多个管道排序的,因为在 pipelines.py 里面可以定义多个数据管道类,它们执行的先后顺序由 value 来控制,数字越小越先执行;

如果你就一个数据管道类,这个 value 给多少都无所谓;

另外提醒,在 process_item() 最后一定要 return item ,不然存在多个数据管道的时候,后执行的数据管道就拿不到数据了;

好,配置完之后,就可以再次执行了;

5.5、从下层页面解析数据

这部分内容相对来讲是难点,搞懂了这部分,就几乎能处理对大部分数据爬取了;

来,开始燥起来~~

前面我们获取到了帖子的 url 和 title,有同学可能要问了,这个帖子的正文内容哪里;

正文内容在帖子的 url 里面,如果我们要同时获取帖子的正文内容,就需要做以下处理;

正文

5.5.1、回调逻辑

首先,前面获取的 url 不是一个完整的链接,咱们需要稍微处理以下:

class BbsSpiderSpider(scrapy.Spider):
    
    base_url = "https://bbs.deepin.org"

    def parse(self, response):
        item = DeepinBbsSpiderItem()
        post_items = response.css("app-post-pc")
        for post_item in post_items:
            item["url"] = post_item.css("a.post_lin_pc::attr(href)").get().replace("/en", self.base_url)
	# 省略部分代码


我们前面获取的 url 是这样的: /en/post/254787 ,因此做一个替换处理;

然后,咱们拿着这个 url 继续做请求:

class BbsSpiderSpider(scrapy.Spider):
    
    base_url = "https://bbs.deepin.org"

    def parse(self, response):
        item = DeepinBbsSpiderItem()
        post_items = response.css("app-post-pc")
        for post_item in post_items:
            item["url"] = post_item.css("a.post_lin_pc::attr(href)").get().replace("/en", self.base_url)
            yield scrapy.Request(
                url=item["url"], 
                callback=self.post_parse, 
                cb_kwargs={"item": item}
            )

    def post_parse(self, response, **kwargs):
        item = kwargs.get("item")


这里需要用 yield 返回并构造 scrapy.Request 对象,传入三个参数:

  • url 就是下层页面的地址;

  • callback 传入回调函数对象,因为 parse() 这个函数是处理当前页面的逻辑,下层页面就不能在这个函数里面继续处理了,而是要新写一个函数来处理;

    写法和 parse() 类似,函数名可以自己定, 参数仍然是 response 对象;

    注意,参数传入是 callback=self.post_parse,后面没有加括号哈,因为我们不是在这里调用函数,是传入函数对象,也就是只要函数名;

  • cb_kwargs 是为了给 post_parse() 函数传递 item 参数,是一个字典类型,这样在 post_parse(self, response, **kwargs) 里面的 kwargs 就能拿到 item 的值,咱们后续拿到正文之后,继续组装到 item 里面就行了;

5.5.2、下层页面解析

下层页面的解析,逻辑和前面一样,先看下 html 源码:

正文 html

获取正文:

    def post_parse(self, response, **kwargs):
        item = kwargs.get("item")
        post_info = response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall()


post_info 获取的结果为:

['1、系统盘分配了40g,这才一个月就快满了,怎么调大点,后面还有100G空间。', '2、应用商店啥时候放出conky?']


做一个字符串组装:

post_info = "".join(response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall())


这样的话,我们就获取到了正文的数据,添加到 item 对象中:

def post_parse(self, response, **kwargs):
    item = kwargs.get("item")
    post_info = "".join(response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall())
    item["post_info"] = post_info
    yield item


注意,在 items.py 中把新的字段也添加上:

# items.py

class DeepinBbsSpiderItem(scrapy.Item):
    ...
    post_info = scrapy.Field()


最后,跑一下爬虫;

5.5.3、多层数据传递问题

到目前位置,完整的爬虫脚本:

import scrapy
from deepin_bbs_spider.items import DeepinBbsSpiderItem

class BbsSpiderSpider(scrapy.Spider):
    name = "bbs_spider"
    allowed_domains = ["bbs.deepin.org"]
    start_urls = ["https://bbs.deepin.org/?offset=0&limit=20&order=updated_at&where=&languages=zh_CN#comment_title"]
    base_url = "https://bbs.deepin.org"

    def parse(self, response):
        item = DeepinBbsSpiderItem()
        post_items = response.css("app-main-pc > div > div:nth-child(3) > app-post-pc")
        for post_item in post_items:
            item["url"] = post_item.css("a.post_lin_pc::attr(href)").get().replace("/en", self.base_url)
            item["title"] = "".join(post_item.css("span.ng-star-inserted::text").getall()[:2])
            yield scrapy.Request(
                url=item["url"],
                callback=self.post_parse,
                cb_kwargs={"item": item}
            )

    def post_parse(self, response, **kwargs):
        item = kwargs.get("item")
        post_info = "".join(response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall())
        item["post_info"] = post_info
        yield item


使用命令跑一下爬虫:

scrapy crawl bbs_spider -o bbs.csv


你会惊奇的发现,怎么所有的 title 和 url 数据相同,开始怀疑自己逻辑是不是写错了;

其实,我们代码逻辑是没问题的,只不过在多层数据传递的过程中,需要特殊处理下,处理方法很简单:

  • 导入from copy import deepcopy模块,将cb_kwargs={'item': item} 更改为 cb_kwargs={'item': deepcopy(item);
  • 最后一行代码yield item 修改成 yield deepcopy(item)就完全 ok 了;

改完之后再跑一下,简直完美。

5.5.4、多页面爬取

到现在我们怕去了第一页的数据,那还想爬取后面的页怎么办?

有同学说,好办,start_urls 不是一个列表吗,把多个 url 放进去不就完了;

不得不说,这样是可以的,就是不够优雅。

通过仔细观察,我们可以发现一些规律:

多页地址

在地址中只有 offset 参数在变化,第一页是 0,第二页是 1,非常有规律,因此咱们可以动态生成:

class BbsSpiderSpider(scrapy.Spider):
    # start_urls = ["https://bbs.deepin.org/?offset=0&limit=20&order=updated_at&where=&languages=zh_CN#comment_title"]

    def start_requests(self):
        for i in range(5):
            yield scrapy.Request(url=f"https://bbs.deepin.org/?offset={i}&limit=20&order=updated_at&where=&languages=zh_CN#comment_title")


使用 start_requests() 函数替代 start_urls;

在里面写个 for 循环,要爬取多少页填入 range 函数就行了,动态生成多个 scrapy.Request 对象,注意要用 yield 哦~~

5.5.5、完整的示例

爬虫脚本 bbs_spider.py:

from copy import deepcopy

import scrapy

from deepin_bbs_spider.items import DeepinBbsSpiderItem

class BbsSpiderSpider(scrapy.Spider):
    name = "bbs_spider"
    allowed_domains = ["bbs.deepin.org"]
    base_url = "https://bbs.deepin.org"

    def start_requests(self):
        for i in range(5):
            yield scrapy.Request(url=f"https://bbs.deepin.org/?offset={i}&limit=20&order=updated_at&where=&languages=zh_CN#comment_title")

    def parse(self, response):
        item = DeepinBbsSpiderItem()
        post_items = response.css("app-main-pc > div > div:nth-child(3) > app-post-pc")
        for post_item in post_items:
            item["url"] = post_item.css("a.post_lin_pc::attr(href)").get().replace("/en", self.base_url)
            item["title"] = "".join(post_item.css("span.ng-star-inserted::text").getall()[:2])
            yield scrapy.Request(
                url=item["url"],
                callback=self.post_parse,
                cb_kwargs={"item": deepcopy(item)}
            )

    def post_parse(self, response, **kwargs):
        item = kwargs["item"]
        post_info = "".join(
            response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall()
        )
        item["post_info"] = post_info
        yield deepcopy(item)


数据类型 items.py:

import scrapy

class DeepinBbsSpiderItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    url = scrapy.Field()
    title = scrapy.Field()
    post_info = scrapy.Field()


配置 settings.py:(省略了没有启用的配置项)

BOT_NAME = "deepin_bbs_spider"

SPIDER_MODULES = ["deepin_bbs_spider.spiders"]
NEWSPIDER_MODULE = "deepin_bbs_spider.spiders"

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"

# Obey robots.txt rules
ROBOTSTXT_OBEY = True

# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
   "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
   "Accept-Language": "en",
}

# Set settings whose default value is deprecated to a future-proof value
REQUEST_FINGERPRINTER_IMPLEMENTATION = "2.7"
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
FEED_EXPORT_ENCODING = "utf-8"


如果你自己玩起来有点小问题,可以尝试参考我的代码:github.com/mikigo/deep…

6、调试

6.1、数据获取调试

在使用 response.css() 表达式时,通常我们需要进行调试,看表达式写得对不对,当然你可以通过执行爬虫然后打印数据,但是这种方式有点麻烦;

Scrapy 提供了一个快捷的调试方法,在终端输入:

scrapy shell <scrapy url>


<scrapy url> 是你要爬取的地址,比如前面我们想获取帖子正文的内容,可以这样调试:

scrapy shell https://bbs.deepin.org/post/254892


进入终端交互式,输入:

>>> response.css("div.post_conten > div.post_edit.ng-star-inserted > div > div > p::text").getall()
['1、系统盘分配了40g,这才一个月就快满了,怎么调大点,后面还有100G空间。', '2、应用商店啥时候放出conky?']


可以看到返回的结果,如果返回为空,就说明表达式可能有点问题;

6.2、Pycharm Debug

Scrapy 由于封装得比较好,启动爬虫是通过命令行启动,但是这有个问题,就是不支持在编辑器里面 Debug 运行,导致你调试代码过程中可能会不停的在终端启动爬虫,有点费劲;

经过一番折腾,终于道破了天机~

(1)先在工程下随便找一个 py 文件,里面啥也不写,执行一下,然后点这里:

配置1

(2)在系统中找到 scrapy 包中的 cmdline.py 文件,这个你得稍微知道点 Python 包管理的一些知识,比如我的在这里:

/home/mikigo/.local/lib/python3.7/site-packages/scrapy/cmdline.py


(4)在 Name 里面写个你喜欢的名字,比如我写:Scrapy

(4)在 Script path 里面把 cmdline.py 的路径填进去;

(5)在 Parameters 里面填入 Scrapy 的参数:crawl bbs_spider -o bbs.csv;

配置2

(6)点击右下角的 【ok】,在主界面点【Debug】就可以进行调试了,妙啊~~

Debug

7、结束语

到这里 Scrapy 的基础入门就结束了,一般的小网站可以轻松快速的搞定,简直 yyds~~

从完整示例我们不难看出,爬虫脚本简单的 30 来行代码加上简单的配置,就可以爬取大量的数据,而且速度非常快,对比你用 requests 去裸写看看,你会发现差距不是一般的大;

对于其他的一些细节还可以完善,比如:代理、异步、中间件、与其他自动化工具扩展(Selenium),后续精力再补充~~

如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述

Python兼职渠道推荐

学的同时助你创收,每天花1-2小时兼职,轻松搞定生活费.
在这里插入图片描述

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓

爬虫练习,适合新手 一个简单的爬虫代码,适合新手玩一玩,代码很简洁,有兴趣的可以下载看一看。 立即下载

相关推荐

第1部分 基础算法(提高篇)--第2章 二分与三分1439:【SCOI2010】传送带

1439:【SCOI2010】传送带 时间限制: 2000 ms 内存限制: 65536 KB 提交数: 372 通过数: 212 【题目描述】 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间。 【输入】 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整

zqhf123的博客 838

8小时带你入门爬虫!

Requests 是 Python 最久负盛名的 HTTP 库,没有之一;K 神(Kenneth Reitz)的 for humans 系列中最有名的一个;K 神帅照做爬虫、数据分析、接口自动化会经常用到它,非常多有名的 Python 库依赖于 Requests 提供基础能力,比如:httpx(支持异步的 HTTP 库)、locust(性能[负载]测试框架)、HttpRunner(接口自动化框架)等等,都是基于 Requests 构建起来的。

Saki_Python的博客 1814

保姆级教程:用PyBullet在Windows/Mac上快速搭建你的第一个机器人仿真环境(附避坑指南)

本教程详细介绍了如何使用PyBullet在Windows和Mac上快速搭建机器人仿真环境,包括Python环境配置、依赖安装避坑指南、首个机械臂仿真实现及性能优化技巧。通过分步指导和实战代码,帮助初学者轻松入门机器人仿真技术。

weixin_42526087的博客 407

初学Python之爬虫的简单入门

爬虫的全称为网络爬虫,简称爬虫,别名有网络机器人,网络蜘蛛等等。网络爬虫是一种自动获取网页内容的程序,为搜索引擎提供了重要的数据支撑。搜索引擎通过网络爬虫技术,将互联网中丰富的网页信息保存到本地,形成镜像备份。我们熟悉的谷歌、百度本质上也可理解为一种爬虫。如果形象地理解,爬虫就如同一只机器蜘蛛,它的基本操作就是模拟人的行为去各个网站抓取数据或返回数据。

xxue345678的博客 2250

SAP预扣税配置实战:从BP创建到外部接口集成的完整流程

本文详细拆解了SAP S/4HANA中预扣税配置与集成的完整实战流程。内容涵盖从业务伙伴(BP)架构下的数据存储理解、后台基础配置,到针对批量处理场景,如何绕过标准BAPI,采用直接更新核心表LFBW的策略进行高效开发。最后,文章探讨了与外部接口集成的多种模式与数据流设计,为财务顾问和ABAP开发人员提供了一套清晰、可落地的解决方案。

weixin_29204749的博客 415

基于微信小程序的垃圾分类系统,附源码

垃圾分类小程序管理员功能有个人中心,管理员管理,意见反馈管理,视频类型管理,垃圾类型管理,新闻类型管理,论坛信息管理,环保视频管理,环保知识管理,垃圾信息管理,环保新闻管理,用户管理,知识问答试卷管理,试题管理,测试管理,轮播图管理。用户可以在微信小程序上面注册登录,查看各种环保信息和垃圾信息,还可以参加知识问答等操作。垃圾分类小程序的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。

Java徐师兄的博客 2076

分享Python7个爬虫小案例(附源码)

① Python所有方向的学习路线图,清楚各个方向要学什么东西② 600多节Python课程视频,涵盖必备基础、爬虫和数据分析③ 100多个Python实战案例,含50个超大型项目详解,学习不再是只会理论④ 20款主流手游迫解 爬虫手游逆行迫解教程包⑤ 爬虫与反爬虫攻防教程包,含15个大型网站迫解⑥ 爬虫APP逆向实战教程包,含45项绝密技术详解⑦ 超300本Python电子好书,从入门到高阶应有尽有⑧ 华为出品独家Python漫画教程,手机也能学习。

xzp740813的博客 3087

【2021末九软工边缘人保研】川大-中科院网络中心-华师夏令营+哈工大本-中科院网络中心-西交-厦大-中山-武大-北航预推免

2021末九软工边缘人保研记录一、写在前面二、个人背景 一、写在前面 2020年计算机保研可谓是诸神黄昏,卷的头破血流(指我等菜鸡)。疫情的原因,今年的夏令营和预推免基本全部改为线上,机试取消,能不能拿到offer基本完全取决于背景以及面试表现(当然也有个别头铁非要机试,甚至笔试的学校)。大佬们offer收割不停,我等边缘人只能看着一封封拒信发呆。 这种情况下,只有985 Rank5%以及211 Rank2%之前的大佬能够较为轻松地拿到面试入场券。贴一个上交电院夏令营要求你们感受一下: 预推免相比起夏令营

weixin_43222706的博客 4235

初学者应如何入门爬虫?

初学者应如何入门爬虫? 首先,明确一点,爬虫并不是 Python 特有的,只要是可以处理 http 请求,使用哪种编程语言关系并不大。 既然这么说为什么市面上关于爬虫大多和 Python 语言挂钩呢? 因为 Python 的入门简单,上手快,而且有很多前辈们写好的轮子,用 Python 写爬虫相当于站在巨人的肩膀上摸高,舒服~ 那么初学者应该如何学爬虫呢? 这个时候需要捋清楚一个逻辑,爬虫是做什么的,爬虫是在互联网上定向抓取数据的程序 既然是抓取数据那么就会牵扯到获取数据、解析数据、数据存储三个部分,那么入

m0_59235699的博客 599

2小时用Trae搭建全功能CMS系统

在前文中,我们使用Trae从零搭建了一个用户文档站点,仅用不到2小时就实现了用户注册登录和文档的增删改查功能,且无需编写任何代码。本节我们将在此基础上,构建一个CMS后台管理系统,包含用户管理和文档管理两大功能模块。

2501_92019101的博客 540

pyradiomics使用——1. 医学影像的组学特征值(Radiomics Features)提取

文章目录1. 使用插件1.1 插件安装1.2 插件使用2. 使用python代码2.1 安装2.2 使用2.2.1 官方示例2.2.2 快速使用2.2.3 其它使用3. 组学特征字段意义说明 Github地址:https://github.com/AIM-Harvard/pyradiomics 官方文档地址:https://pyradiomics.readthedocs.io/en/latest/features.html 1. 使用插件 从pyradiomics的Github仓库中可以知道,pyradio

啷个哩个啷 7369

爬虫入门教程

文章目录前言一、学习爬虫前所需掌握的内容二、爬取数据2.1 如何存储数据2.1 获取网络数据2.2 获取网络数据json2.3 获取图片数据三、提取数据3.1 使用XPATH 前言 本文用于记录学习爬虫的过程,将持续进行更新与修正。本文所学习的案例为:爬取豆瓣电影的评分、评价等信息,进行数据分析。 一、学习爬虫前所需掌握的内容 首先我们进入豆瓣,我们要爬取电影的评分、评价等信息。 提取这些信息用处很大,例如对于评价信息,可以提取词云做一个词云图,提取里面出现最多的字眼并展现出来进行分析。 如果我们

InnerPeaceHQ的博客 7901

【006】深入了解C++中的进制转换:二进制、八进制、十进制、十六进制

二进制:0~1,以0b开头,bitset< 8 >输出。八进制:0~7,以0开头,oct输出。十进制:0~9,以数字开头,cout默认输出十进制。十六进制:0 ~ 9和A ~ F,以0x开头,hex输出,不区分正负。n进制:0~n-1。C++ 中常见的数字进制有十进制、二进制、八进制、十六进制。从十进制转换到其他进制:二进制:使用除以 2 取余数的方法,将得到的余数倒序排列即为二进制。八进制:使用除以 8 取余数的方法,将得到的余数倒序排列即为八进制。

Lion_Long的博客 2612

python爬虫入门教程(一):开始爬虫前的准备工作

python爬虫(数据采集)入门教程

笔墨留年。 8万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Python 爬虫入门的教程(1小时快速入门、简单易懂、快速上手)_一小时入门 python 3 网络爬虫

首先在 PyCharm 中安装 requests 库,为此打开 PyCharm,单击“File”(文件)菜单,选择“Setting for New Projects…”命令,如图 4 所示。图 4选择“Project Interpreter”(项目编译器)命令,确认当前选择的编译器,然后单击右上角的加号,如图 5 所示。图 5在搜索框输入:requests(注意,一定要输入完整,不然容易出错),然后单击左下角的“Install Package”(安装库)按钮。如图 6 所示:图 6。

2401_86372526的博客 3161

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

零基础学Python网络爬虫案例实战全流程详解(入门与提高篇)

笔者编写的《Python金融大数据挖掘与分析全流程详解》于2019年出版面市后,陆续有不少读者表示对该书的爬虫部分非常感兴趣,想做进一步的学习。笔者由此萌生了一个想法:专门针对Python爬虫技术编写一套书籍,在保留之前核心内容的基础上,新增更多实战案例,方便读者在练中学,并体会Python爬虫在实战中的应用。

mirana的专栏 3013

网络爬虫的分类与应用

这类爬虫需要处理大量的数据,并且需要高效的算法来管理和存储这些数据。它们只抓取与特定主题相关的网页,节省了带宽和计算资源,适用于需要特定信息的应用场景。例如,一个专注于医学信息的聚焦爬虫只会抓取与医学相关的网页。(Incremental Web Crawler)只抓取内容发生变化的网页或新产生的网页。这种爬虫在更新时只更新变化的部分,适用于需要频繁更新数据的网站。例如,新闻网站的爬虫可以定期检查新文章,并只抓取新增的内容。增量式网络爬虫只抓取内容发生变化的网页或新产生的网页。

浪里个狼游记 1674

Python 爬虫入门的教程(1小时快速入门、简单易懂、快速上手)

这是一篇详细介绍 Python爬虫入门的教程,从实战出发,适合初学者。读者只需在阅读过程紧跟文章思路,理清相应的实现代码,30 分钟即可学会编写简单的 Python 爬虫。

weixin_55154866的博客 1303

12款最常使用的网络爬虫工具推荐_爬虫软件

免费软件为你的网络抓取提供匿名Web代理服务器,你提取的数据将在存档数据之前在的服务器上托管两周,或者你可以直接将提取的数据导出到JSON或CSV文件。OutWit Hub大多功能都是免费的,能够深入分析网站,自动收集整理组织互联网中的各项数据,并将网站信息分割开来,然后提取有效信息,形成可用的集合。用户可以轻松索引和搜索抓取的结构化数据。Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

2501_90317968的博客 2933

基于Python的网络爬虫应用研究

本研究基于Python开发高效网络爬虫系统,采用Scrapy框架结合requests、Selenium等技术实现静态/动态网页采集,集成XPath解析、IP代理池等关键技术,数据获取准确率达98.5%,爬取速度500-800条/分钟。系统模块化设计支持电商、新闻、学术等多场景应用,严格遵循合规要求,显著提升数据采集效率。测试表明系统运行稳定,可支持企业竞争分析、舆情监测等需求,具有广泛应用前景。

2301_79745346的博客 1058

入门爬虫,爬取数据这一篇就够了!!!

有小伙伴问,新手该怎么开始学习爬虫。其实说实在的入门爬虫真的非常容易。于是我就针对如何入门爬虫进行了总结如果你不会用爬虫爬数据,但是你又经常需要把某些网站上的数据导入到E...

优快云资讯 8091

基于网络爬虫技术的新闻聚合网站系统

摘要:本文设计并实现了一个基于网络爬虫技术的新闻聚合网站系统,旨在解决互联网时代新闻资讯分散、获取效率低的问题。系统采用四层架构,通过Python爬虫框架实现多源新闻采集,结合BeautifulSoup、XPath等技术进行数据解析与去重处理,利用Spring Boot和Vue.js搭建前后端服务。测试显示系统爬取成功率≥98%,正文提取准确率96.3%,延迟≤2分钟。未来将拓展个性化推荐和多语言支持功能,为用户提供高效便捷的一站式新闻获取平台。(150字)

2301_81142448的博客 1640

2026最值得选的 10 款网络爬虫工具对比,避开 90% 的选型坑前言

的爬虫工具,只有适配的工具。如果是个人小项目、技术试错,Scrapy、Selenium等开源工具可以满足需求,但要承担代理配置、运维和反爬的风险;如果是企业级需求,追求稳定、高效、低维护,Bright Data Web Scraper API无疑是最优选择,其内置的大规模代理网络和智能代理策略,可大幅降低企业的技术投入和成本消耗。Bright Data无论是可视化操作还是API调用,均无需配置代理,2000+预构建模板可直接启动爬取,复杂动态页面、强反爬场景均能稳定应对,数据完整度远超Octoparse。

编码世界 9575
上一篇: 学会Python在家办公搞副业能有多爽?
下一篇: “隐形贫困者”自学Python做副业
田野猫咪
博客等级 码龄4年 5080粉丝 502原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值