1. 程式人生 > >scrapy遞迴解析和post請求

scrapy遞迴解析和post請求

遞迴解析

遞迴爬取解析多頁頁面資料

每一個頁面對應一個url,則scrapy工程需要對每一個頁碼對應的url依次發起請求,然後通過對應的解析方法進行作者和段子內容的解析。

實現方案:

    1.將每一個頁碼對應的url存放到爬蟲檔案的起始url列表(start_urls)中。(不推薦)

    2.使用Request方法手動發起請求。(推薦)

import scrapy
from choutiPro.items import ChoutiproItem


class ChoutiSpider(scrapy.Spider):
    name 
= 'chouti' # allowed_domains = ['www.xxx.com'] # 通用url的封裝 url = 'https://dig.chouti.com/r/scoff/hot/%d' pageNum = 1 start_urls = ['https://dig.chouti.com/r/scoff/hot/1'] def parse(self, response): div_list = response.xpath('//div[@id="content-list"]/div') for div in
div_list: title = div.xpath('./div[3]/div[1]/a/text()').extract_first() author = div.xpath('./div[3]/div[2]/a[4]/b/text()').extract_first() # item = ChoutiproItem() item['title'] = title item['author'] = author yield item
if self.pageNum < 5: # 頁碼的一個範圍 # 封裝集成了一個新的頁碼的url self.pageNum += 1 new_url = format(self.url % self.pageNum) # 手動的請求傳送:callback表示的指定的解析方法 yield scrapy.Request(url=new_url, callback=self.parse) # 在scrapy框架中yield的使用場景: # 1.yield item:向管道提交item # 2.yield scrapy.Request():進行手動請求傳送

items

import scrapy


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

pipelines

class ChoutiproPipeline(object):
    def process_item(self, item, spider):
        print(f"{item['title']}:{item['author']}")
        # 持久化儲存,測試沒寫
        return item

settings

BOT_NAME = 'choutiPro'
# 使用UA
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
SPIDER_MODULES = ['choutiPro.spiders']
NEWSPIDER_MODULE = 'choutiPro.spiders'


# Crawl responsibly by identifying yourself (and your website) on the user-agent
# 關閉root協議
ROBOTSTXT_OBEY = False

# 開啟管道
ITEM_PIPELINES = {
    'choutiPro.pipelines.ChoutiproPipeline': 300,
}

五大核心元件工作流程

    • 引擎(Scrapy)
      用來處理整個系統的資料流處理, 觸發事務(框架核心)
    • 排程器(Scheduler)
      用來接受引擎發過來的請求, 壓入佇列中, 並在引擎再次請求的時候返回. 可以想像成一個URL(抓取網頁的網址或者說是連結)的優先佇列, 由它來決定下一個要抓取的網址是什麼, 同時去除重複的網址
    • 下載器(Downloader)
      用於下載網頁內容, 並將網頁內容返回給蜘蛛(Scrapy下載器是建立在twisted這個高效的非同步模型上的)
    • 爬蟲(Spiders)
      爬蟲是主要幹活的, 用於從特定的網頁中提取自己需要的資訊, 即所謂的實體(Item)。使用者也可以從中提取出連結,讓Scrapy繼續抓取下一個頁面
    • 專案管道(Pipeline)
      負責處理爬蟲從網頁中抽取的實體,主要的功能是持久化實體、驗證實體的有效性、清除不需要的資訊。當頁面被爬蟲解析後,將被髮送到專案管道,並經過幾個特定的次序處理資料。

下圖是一個請求再返回來的流程

紅色是傳送請求

藍色是返回的流程

post請求

其實是因為爬蟲檔案中的爬蟲類繼承到了Spider父類中的start_requests(self)這個方法,該方法就可以對start_urls列表中的url發起請求:

    # 原始作用:將起始url料表中url進行GET請求
    # def start_requests(self):  # 模擬get請求的簡化流程
    #     for url in self.start_urls:
    #         yield scrapy.Request(url=url,callback=self.parse)

實現post請求其實就是重寫父類的start_requests

    # 重寫 父類的 start_requests,讓其進行POST請求
    def start_requests(self):
        data = {
            'kw': 'dog'
        }
        for url in self.start_urls:
            # scrapy.FormRequest:指 POST 請求
            # callback=self.parse 指回調函式
            # formdata=data  指post請求傳送的資料
            yield scrapy.FormRequest(url=url, callback=self.parse, formdata=data)

列如百度翻譯我就可以這樣傳送post請求

# -*- coding: utf-8 -*-
import scrapy


class PostSpider(scrapy.Spider):
    name = 'post'
    allowed_domains = ['www.xxx.com']
    start_urls = ['https://fanyi.baidu.com/sug']

    # 原始作用:將起始url料表中url進行GET請求
    # def start_requests(self):  # 模擬get請求的簡化流程
    #     for url in self.start_urls:
    #         yield scrapy.Request(url=url,callback=self.parse)

    # 重寫 父類的 start_requests,讓其進行POST請求
    def start_requests(self):
        data = {
            'kw': 'dog'
        }
        for url in self.start_urls:
            # scrapy.FormRequest:指 POST 請求
            # callback=self.parse 指回調函式
            # formdata=data  指post請求傳送的資料
            yield scrapy.FormRequest(url=url, callback=self.parse, formdata=data)

    def parse(self, response):
        # print(response.bady)
        print(response.text)
baidu—post

訪問人人個人首頁

# -*- coding: utf-8 -*-
import scrapy


class LoginSpider(scrapy.Spider):
    name = 'login'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['http://www.renren.com/ajaxLogin/login?1=1&uniqueTimestamp=201873958471']

    def start_requests(self):
        formdata = {
            'email': '17701256561',
            'icode': '',
            'origURL': 'http://www.renren.com/home',
            'domain': 'renren.com',
            'key_id': '1',
            'captcha_type': 'web_login',
            'password': '7b456e6c3eb6615b2e122a2942ef3845da1f91e3de075179079a3b84952508e4',
            'rkey': '44fd96c219c593f3c9612360c80310a3',
            'f': 'https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3Dm7m_NSUp5Ri_ZrK5eNIpn_dMs48UAcvT-N_kmysWgYW%26wd%3D%26eqid%3Dba95daf5000065ce000000035b120219',
        }
        for url in self.start_urls:
            yield scrapy.FormRequest(url=url, formdata=formdata, callback=self.parse)

    def parse(self, response):
        url = 'http://www.renren.com/960481378/profile'

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

    def personalPage(self, response):
        page_text = response.text
        print(response)
人人個人首頁