scrapy多个yield反复横跳

博客主要围绕Scrapy展开,重点提及了Scrapy里多个yield scrapy.Request的相关内容,涉及Python和XPath技术。

scrapy里多个yield scrapy.Request

import scrapy
import re
import requests
import json
import time
from ..items import InduspiderItem
from newspaper import Article
from gne import GeneralNewsExtractor
from date_extractor import extract_date
from lxml import etree
from urllib import parse


class KathmanduSpider(scrapy.Spider):
    name = 'Kathmandu'
    allowed_domains = ['kathmandupost.com']
    start_urls = ['https://kathmandupost.com/politics']

    def parse(self, response):
        list_ = response.xpath('//div/article/a/@href')
        for u in list_:
            item = InduspiderItem()
            c = u.get()
            url = 'https://kathmandupost.com' + c
            item['_id'] = url
            item['yuming'] = 'www.kathmandupost.com'
            yield scrapy.Request(url=url, meta={'meta_1': item}, callback=self.get_two_page)
        html = response.body
        tex = html.decode(response.encoding)
        regex = "<script>var last = '(.*?)';var requestRunning"
        par = re.compile(regex, re.S)
        r_ = par.findall(tex)
        param = parse.urlencode({'pub': r_[0]})
        one_url = 'https://kathmandupost.com/politics?html=1&{}'.format(param)
        yield scrapy.Request(url=one_url, headers={'referer': 'https://kathmandupost.com/politics',
                                                   'x-requested-with': 'XMLHttpRequest'}, callback=self.get_url)

    def get_url(self, response):
        # header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
        #                         'Chrome/90.0.4430.212 Safari/537.36',
        #           'referer': 'https://kathmandupost.com/politics',
        #           'x-requested-with': 'XMLHttpRequest'
        #           }

        # html = requests.get(url=url, headers=header).text
        html = response.body
        tex = html.decode(response.encoding)
        ht = json.loads(tex)
        pars = etree.HTML(ht['news_list_html'])
        lis = pars.xpath('//div/article/a/@href')
        for u in lis:
            item = InduspiderItem()
            d = u
            url = 'https://kathmandupost.com' + d
            item['_id'] = url
            item['yuming'] = 'www.kathmandupost.com'
            yield scrapy.Request(url=url, meta={'meta_1': item}, callback=self.get_two_page)

        tm = ht['date']
        par = parse.urlencode({'pub': tm})
        ur = 'https://kathmandupost.com/politics?html=1&{}'.format(par)
        yield scrapy.Request(url=ur, headers={'referer': 'https://kathmandupost.com/politics',
                                              'x-requested-with': 'XMLHttpRequest'}, callback=self.get_url)

    def get_two_page(self, response):
        html = response.body
        tex = html.decode(response.encoding)
        extr = GeneralNewsExtractor()
        resul = extr.extract(tex, author_xpath='//div/h5/a/text()',
                             publish_time_xpath='//div/div[@class="updated-time"][2]/text()')

        news = Article('')
        news.download(html)
        news.parse()

        item = response.meta['meta_1']
        item['title'] = resul['title']
        item['updatetime'] = resul['publish_time']
        item['author'] = resul['author']
        item['content'] = resul['content']
        item['img'] = news.top_image
        item['timestamp'] = time.time()
        item['video'] = news.movies
        b = extract_date(resul['publish_time'])
        item['format_time'] = b

        yield item

Scrapy 框架中,`yield` 通常用于生成请求(`scrapy.Request`)并指定一个回调函数来处理响应。默认情况下,回调函数接受 `response` 参数,但可以通过 `meta` 属性将额外的数据传递给回调函数。 为了在回调函数中接收多个参数,可以将需要的值封装在 `meta` 字典中,并在回调函数中通过 `response.meta` 提取这些值。这样可以实现多个参数的传递。 ### 示例代码 以下是一个使用 `meta` 传递多个值的示例: ```python import scrapy class ExampleSpider(scrapy.Spider): name = 'example_spider' def start_requests(self): urls = [ 'http://example.com/page1', 'http://example.com/page2' ] for url in urls: yield scrapy.Request( url=url, callback=self.parse, meta={ 'param1': 'value1', 'param2': 'value2' } ) def parse(self, response): # 从 meta 中提取传递的参数 param1 = response.meta['param1'] param2 = response.meta['param2'] # 输出传递的参数和当前页面的标题 yield { 'url': response.url, 'title': response.xpath('//title/text()').get(), 'param1': param1, 'param2': param2 } ``` 在上述代码中,`start_requests` 方法生成请求时,通过 `meta` 传递了两个参数 `param1` 和 `param2`。在 `parse` 回调函数中,通过 `response.meta` 获取这些参数,并将其与解析到的数据一起返回。 ### 注意事项 - 确保 `meta` 中的键名唯一且有意义,以避免与其他中间件或扩展冲突。 - 如果需要传递复杂数据结构(如列表或嵌套字典),可以直接将其放入 `meta` 中。 - 避免在 `meta` 中传递大量数据,以免影响性能。 这种方法利用了 Scrapy 的 `Request.meta` 特性,能够灵活地在请求之间传递数据[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值