【爬虫】4.4 Scrapy 爬取网站数据

       目录

1. 建立 Web 网站

2. 编写 Scrapy 爬虫程序


        为了说明 scrapy 爬虫爬取网站多个网页数据的过程,用 Flask 搭建一个小型的 Web 网站。

1. 建立 Web 网站

(1)books.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>books</title>
</head>
<body>
    <h3>计算机</h3>
    <ul>
        <li><a href="database.html">数据库</a></li>
        <li><a href="program.html">程序设计</a></li>
        <li><a href="network.html">计算机网络</a></li>
    </ul>
</body>
</html>

(2)databse.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>database</title>
</head>
<body>
    <h3>数据库</h3>
    <ul>
        <li><a href="mysql.html">MySQL数据库</a></li>
    </ul>
    <a href="books.html">Home</a>
</body>
</html>

(3)program.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>program</title>
</head>
<body>
    <h3>程序设计</h3>
    <ul>
        <li><a href="python.html">Python程序设计</a></li>
        <li><a href="java.html">Java程序设计</a></li>
    </ul>
    <a href="books.html">Home</a>
</body>
</html>

(4)network.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>network</title>
</head>
<body>
    <h3>计算机网络</h3>
    <a href="books.html">Home</a>
</body>
</html>

(5)mysql.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>mysql</title>
</head>
<body>
    <h3>MySQL数据库</h3>
    <a href="books.html">Home</a>
</body>
</html>

(6)python.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>python</title>
</head>
<body>
    <h3>Python程序设计</h3>
    <a href="books.html">Home</a>
</body>
</html>

(7)java.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>java</title>
</head>
<body>
    <h3>Java程序设计</h3>
    <a href="books.html">Home</a>
</body>
</html>

        【问题】编写一个爬虫程序爬取这个网站所有的页面的<h3>标题文字。

服务器程序 server.py 如下:

import flask
import os

app = flask.Flask(__name__)


def getFile(fileName):
    data = b""
    fileName = "web_html/" + fileName  # 将7个html页面放到web_html目录下,做了个路径拼接
    if os.path.exists(fileName):
        fobj = open(fileName, "rb")
        data = fobj.read()
        fobj.close()
    return data


@app.route("/")
def index():
    return getFile("books.html")


@app.route("/<section>")
def process(section):
    data = ""
    if section != "":
        data = getFile(section)
    return data


if __name__ == "__main__":
    app.run()

2. 编写 Scrapy 爬虫程序

        仍然使用4.1节中的爬虫程序项目,重新编写MySpider.py程序

爬虫程序 MySpider.py 如下:

import scrapy


class MySpider(scrapy.Spider):
    name = "mySpider"

    def start_requests(self):
        url = 'http://127.0.0.1:5000'
        yield scrapy.Request(url=url, callback=self.parse)

    # 函数start_requests可以用start_urls替换
    # start_urls = ['http://127.0.0.1:5000']

    def parse(self, response, **kwargs):
        try:
            print(response.url)
            data = response.body.decode()
            selector = scrapy.Selector(text=data)
            print(selector.xpath("//h3/text()").extract_first())
            links = selector.xpath("//a/@href").extract()
            for link in links:
                url = response.urljoin(link)
                yield scrapy.Request(url=url, callback=self.parse)
        except Exception as err:
            print(err)

开启 服务器server.py

执行run.py如下:

http://127.0.0.1:5000
计算机
http://127.0.0.1:5000/network.html
计算机网络
http://127.0.0.1:5000/program.html
程序设计
http://127.0.0.1:5000/database.html
数据库
http://127.0.0.1:5000/mysql.html
MySQL数据库
http://127.0.0.1:5000/java.html
Java程序设计
http://127.0.0.1:5000/books.html
计算机
http://127.0.0.1:5000/python.html
Python程序设计

        scrapy 自动筛选已经访问过的网站,我们来分析程序的执行过程:

(1)    

start_urls=['http://127.0.0.1:5000']

这是入口地址,访问这个地址成功后会回调parse函数;

(2)    

def parse(self, response):

这是回调函数,该函数的response对象包含了网站返回的信息;

(3)    

data=response.body.decode()          

selector=scrapy.Selector(text=data)

网站返回的response.body的二进制数据,要decode转为文本,然后建立Selector对象;

(4)

print(selector.xpath("//h3/text()").extract_first())

获取网页中的<h3>标题的文本,这就是要爬取的数据,为了简单起见这个数据只有一项;

(5)

links=selector.xpath("//a/@href").extract()

获取所有的<a href=...>链接的 href值,组成links列表;

(6)

for link in links:            

        url=response.urljoin(link)              

         yield scrapy.Request(url=url,callback=self.parse)

访问links的每个link,通过urljoin函数与response.url地址组合成完整的 url地址,再次建立Request对象,回调函数仍然为parse,即这个parse函数会被递归调用。其中使用了yield语句返回每个Request对象,这是 scrapy程序的要求。


下一篇文章:如何进一步的提高Scrapy爬虫的爬取速度? 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值