scrapy项目的代码书写流程

scrapy项目的代码书写流程

第一步:选择一个文件夹,进入控制台,输入命令scrapy startproject qidian

第二步:切换到内层的spiders文件加 cd qidian/qidian/spiders   输入命令 scrapy genspider qidianyuedu  qidian.com(域名)

注意点:爬虫的名字 qidianyuedu 不能和工程的名字重复

第三步:在工程的路径下,建立一个启动文件starts.py

1 from scrapy import cmdline
2 cmdline.execute(["scrapy","crawl","qidianyuedu"])

第四步:修改settings文件,主要修改内容如下

# 添加headers
USER_AGENT = ‘Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36‘

# robot.txt
ROBOTSTXT_OBEY = False

# 打开pipeline
ITEM_PIPELINES = {
   ‘qidian.pipelines.QidianPipeline‘: 300,
}

第五步:根据要爬取的数据,设置相对应的item字段

class QidianItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = Field()
    url = Field()
    author = Field()
    category = Field()
    status = Field()
    bref = Field()

第六步:书写pipeline,这里以将数据保存到mysql为例

import pymysql

class QidianPipeline(object):

    def __init__(self):
        self.db = pymysql.connect(host="xx.xx.xx.xx",
                                  port=3306,
                                  user="root",
                                  password="xxx",
                                  db="xxx",
                                  charset="utf8mb4")
        self.cur = self.db.cursor()




    def process_item(self, item, spider):

        sql = """insert into qqyuedu(title,url,author,category,
                status,bref)
                VALUES (%s,%s,%s,%s,%s,%s)"""
        data = (item["title"],item["url"],item["author"],item["category"],item["status"]
                ,item["bref"])
        try:
            self.cur.execute(sql,data)
        except:
            pass
        else:
            self.db.commit()
        return item

    def __del__(self):
        self.cur.close()
        self.db.close()

第七步:书写爬虫主要的程序 spiders 下面的那个文件

分成两种格式进行总结:

1. 使用starts_url的方式,使用offset配合翻页

class Douban250Spider(scrapy.Spider):
    name = ‘douban250‘
    offset = 0
    allowed_domains = [‘movie.douban.com‘]
    start_urls = [‘https://movie.douban.com/top250?start=0&filter=‘]

    def parse(self, response):
        item = DoubanItem()
        li_list = response.css(".grid_view li")
        for li in li_list:
            item["name"] = li.css(".info")[0].xpath(".//span[@class=\"title\"][1]/text()")[0].extract()
            item["info"] =  "".join("".join(li.css(".info .bd")[0].xpath("./p//text()").extract()).split())
            item["score"] = float(li.css(".info .star")[0].xpath("./span[@class=\"rating_num\"]/text()")[0].extract())
            item["access"] = li.css(".info .star")[0].xpath("./span[4]/text()")[0].extract()
            item["bref"]= li.css(".info .quote")[0].xpath("./span[@class=\"inq\"]/text()")[0].extract()
            yield item

        if self.offset < 250:
            self.offset += 25
            url = "https://movie.douban.com/top250?start="+str(self.offset)+"&filter="
            yield scrapy.Request(url,callback=self.parse,dont_filter=True)

2.重写start_requests

class QidianyueduSpider(scrapy.Spider):
    name = ‘qidianyuedu‘
    allowed_domains = [‘book.qidian.com‘]

    def start_requests(self):
        page_num = self.get_page_num()
        for i in range(1,page_num+1):
            url = "https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page="+str(i)
            yield scrapy.Request(url,callback=self.parse,
                                 headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"})

    def parse(self, response):
        li_list = response.css(".book-img-text li")
        for li in li_list:
            item = QidianItem()
            item["title"] = li.css(".book-mid-info h4 a::text")[0].extract()
            item["url"] = "https:"+li.css(".book-mid-info h4 a::attr(href)")[0].extract()
            item["author"] = li.css(".book-mid-info .author a")[0].xpath("./text()")[0].extract()
            category = ""
            a_list = li.css(".book-mid-info .author a")[1:]
            for a in a_list:
                a_text = a.css("a::text")[0].extract()
                category += a_text
                category += " "
            item["category"] = category.strip()
            item["status"] = li.css(".book-mid-info .author span::text")[0].extract()
            yield item

第八步:解析数据,在解析数据的时候我们可以借助着scrapy shell xxxxx 要爬取的网站  进入代码输入区域,首先输入view(response) 查看要爬取的网页是否是目标网页,然后在使用css/xpath的方式进行提取

注意:当我们提取的网络中的数据文字多,想进行拼接操作的时候,会有很多空白字符进行妨碍,解决方法 

 1 "".join("".join(li.css(".info .bd")[0].xpath("./p//text()").extract()).split()) 

从shell中将所有要提取的数据提取成功了,在转移到代码中即可,代码见第七步

深化一个问题,就是item分裂的问题

在一个页面的提取并不满足所有的item数据,需要深层次的网页的数据提取,这个时候就需要进行item的传递,实际上就是Request(url,meta={"meta":item},callback=self.parse_detail)的传递,和item = response.meta["meta"]

的解包,在新的解析函数中继续使用,在yield返回即可

class QidianyueduSpider(scrapy.Spider):
    name = ‘qidianyuedu‘
    allowed_domains = [‘book.qidian.com‘]

    def get_page_num(self):
        headers = {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
        url = "https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page=1"
        res = requests.get(url, headers=headers)
        html = res.content.decode("utf-8")
        soup = BeautifulSoup(html, "lxml")
        num = int(soup.select(".count-text span")[0].get_text())
        if num%20 == 0:
            page = num//20
        else:
            page = (num//20)
        return page

    def start_requests(self):
        page_num = self.get_page_num()
        for i in range(1,page_num+1):
            url = "https://www.qidian.com/all?orderId=&style=1&pageSize=20&siteid=1&pubflag=0&hiddenField=0&page="+str(i)
            yield scrapy.Request(url,callback=self.parse,
                                 headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"})

    def parse(self, response):
        li_list = response.css(".book-img-text li")
        for li in li_list:
            item = QidianItem()
            item["title"] = li.css(".book-mid-info h4 a::text")[0].extract()
            item["url"] = "https:"+li.css(".book-mid-info h4 a::attr(href)")[0].extract()
            item["author"] = li.css(".book-mid-info .author a")[0].xpath("./text()")[0].extract()
            category = ""
            a_list = li.css(".book-mid-info .author a")[1:]
            for a in a_list:
                a_text = a.css("a::text")[0].extract()
                category += a_text
                category += " "
            item["category"] = category.strip()
            item["status"] = li.css(".book-mid-info .author span::text")[0].extract()
            yield scrapy.Request(item["url"],meta={"meta":item},
                                 callback=self.parse_detial,
                                 headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"})


    def parse_detial(self,response):
        item = response.meta["meta"]
        item["bref"] = "".join("".join(response.css(".book-intro p")[0].xpath(".//text()").extract()).split())
        yield item

相关推荐