scrapy-spiders 爬虫 request

一、scrapy

环境配置:直接conda 一个环境,然后

conda create -n pachong python=3.7

安装包

pip install scrapy

激活环境

conda activate pachong

使用scrapy创建一个项目

scrapy startproject 项目名

如(项目名)pachong
在这里插入图片描述
然后进入目录会有以下文件:
在这里插入图片描述

Scrapy完成爬虫需要涉及的文件和步骤

  • 新建项目 (scrapy startproject xxx):新建一个新的爬虫项

  • 明确目标(编写items.py):明确你想要抓取的目标

  • 制作爬虫(spiders/xxspider.py):制作爬虫开始爬取网页

  • 中间件(middlewares.py):处理请求(比如加头,代理ip等)

  • 存储内容(pipelines.py):设计管道存储爬取内容

  • 全局的设置(setting.py):对自定义的方法进行调用

二、使用步骤

1.item.py

爬取的网站:https://www.kuaidaili.com/free/inha/
获取其免费的ip

在这里插入图片描述
从中我们需要一个是ipport。所以在items.py文件下编写

import scrapy
class GetIpItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    ip=scrapy.Field()
    port=scrapy.Field()

已经知道要获取什么数据,现在是如何通过网页进行获取

2.制作爬虫

进入spiders 文件夹里,新建一个get_ip.py文件,进行编写,爬取数据。
网页右击检查(chrome)
在这里插入图片描述
如图,获取当前页所有ip。在指定源码位置右击copy 选在 copy xpath,则获得:
//*[@id=“list”]/table/tbody。这样就获取了全部的ip信息。然后 .//tr . 进入当前目录下的所有tr文件,这样就返回一个list集合

代码如下(示例):

import os
import scrapy
import requests
import random
import time
from lxml import etree
from get_ip.items import GetIpItem
class get_ip(scrapy.Spider):
    name='get_ip' # 用来启动爬虫的命名,同一个目录下,是唯一的
    def start_requests(self):  # 启动之后第一步是调用这里
        url='https://www.kuaidaili.com/free/inha/1/'
        yield scrapy.Request(url=url,callback=self.parse)       # 返回响应给parse进行处理

    def parse(self, response,**kwargs):  # 处理响应,获取想要的资源
        ip_list=response.xpath('//*[@id="list"]/table/tbody').xpath('.//tr')
        item=GetIpItem()
        for link in ip_list:		#text() 获取文本,如果是当前标签下其他方法,可以用(如@href)
            item['ip']=link.xpath('.//td[1]/text()').extract()  # 使用extract()  就成了一个字符串了
            item['host']=link.xpath('.//td[2]/text()').extract()
            yield item      # 这里是使用 yield 到 pipline 类中进行处理,下载保存之类

        # new_links = response.xpath('//a[text()="下一页"]/@href').extract()
        # if new_links and len(new_links) > 0:
        #         # 获取下一页的链接
        #         new_link = new_links[0]
        #         # 再次发送请求获取下一页数据
        #         yield scrapy.Request("https://www.ygdy8.net/html/gndy/china/" + new_link, callback=self.parse)

        for link in new_links:
            new_link=link.xpath('.//a/@href').extract()            # 获取下一页的链接   返回的是list的字符串  如['/free/inha/1/']
            print(new_link)
            time.sleep(4)											# 不能直接一直发送请求,会报错
            if new_link:                                            # 链接不为空则开始下一页
                # 再次发送请求获取下一页数据
                yield scrapy.Request("https://www.kuaidaili.com" + new_link[0], callback=self.parse)

3.中间件

# 设置ip池
import random
from example.settings import IPPOOL
class MyproxiesSpiderMiddleware(object):
    def __init__(self, ip=''):
        self.ip = ip
    def process_request(self, request, spider):
        thisip = random.choice(IPPOOL)
        print("this is ip:" + "https://" + thisip["ipaddr"])
        request.meta["proxy"] = "http://" + thisip["ipaddr"]

4.存储内容

步骤2获得的数据会在pipline进行处理,保存。

from itemadapter import ItemAdapter
import pandas as pd

class GetIpPipeline:
    def __init__(self):
        self.save_csv=pd.DataFrame(columns=['ip','host'])

    def close_spider(self, spider):#重写close_spider回调方法
        self.save_csv.to_csv("movie.csv")

    def process_item(self, item, spider):
        # self.save_text.write(item['ip']+','+item['host'])
        print(item['ip'][0],item['host'][0])
        self.save_csv=self.save_csv.append({'ip':item['ip'][0],'host':item['host'][0]},ignore_index=True)

5.setting的配置

# Obey robots.txt rules  是否遵循机器爬虫,一般fasle,否则会造成有些网站不能爬取
ROBOTSTXT_OBEY = False
COOKIES_ENABLED = False         #禁用cookies,防止某些网站根据Cookie来封锁爬虫。
IPPOOL=[  # ip池
    {"ipaddr": "120.133.60.92:80"},
    {"ipaddr": "183.47.237.251:80"},
]
ITEM_PIPELINES = {
   'get_ip.pipelines.GetIpPipeline': 300,
}


三、request爬虫方式

爬取网站:https://subscene.com/
也是一个电影字幕的网址

1.导包

import requests
from lxml import etree		# 解析 requests 返回的html 页面
import time

2.请求

搜索栏输入我和我的祖国,点击搜索,
在这里插入图片描述
可以从中看出是一个post的请求,定义header信息

no_subscene=[]
movies_is_exist=[]
language_list=[]
header = {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
        "cache-control": "max-age=0",
#         "content-length": "27",
        "content-type": "application/x-www-form-urlencoded",
        "cookie": "_ga=GA1.2.505677917.1634012451; _gid=GA1.2.715886252.1634012451; __cf_bm=Ab8DXP.UZzQf_vsmlftfQQTNhh1IP1RaEEskGCRa9N8-1634117297-0-AQ3K+taJ0uYRxVqeSMtDly6BhQU9ZsHltvE+D9NuCW2eUUI5Acl534W5gxjrlnAUvzwFm2+BkE7DTuwMVpsFud196eGKyaJxhOD1fQSydDPfTsZTSjIu0P4zmZA6b/WcSQ==; _gat=1",
        "origin": "https://subscene.com",
        "referer": "https://subscene.com/subtitles/searchbytitle",
        "sec-ch-ua": '"Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99"',
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": '"Windows"',
        "sec-fetch-dest": "document",
        "sec-fetch-mode": "navigate",
        "sec-fetch-site": "same-origin",
        "sec-fetch-user": "?1",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"}

在这里插入图片描述
这是是发送post请求,附加的数据

#下面的电影名存储的txt文件
for line in open('C:\\Users\\***\\Desktop\\pachong\\example(1)\\example\\example\\no_exist.txt', 'r',
                 encoding='utf-8'):
    line=line.replace('\n','')			# 
# 这里写循环的原因在于,post请求不像get请求那样,返回快,如果一时间访问过多,会报409
    while 1:
        content=requests.post(url="https://subscene.com/subtitles/searchbytitle",data={'query':f'{line}'},headers=header)			# 发送post请求  data 中的字典就是上图的Frome data
        if content.status_code==409:
            time.sleep(3)
            continue
        else:
            break

当请求发送成功之后,会返回一个200 和一个html页面源码,这时候就要使用etree进行解析页面

    etree_html = etree.HTML(content.content)		#将html的内容进行传入etree 进行解析
    text = etree_html.xpath('//*[@id="left"]/div/div/h2/text()')	
    if text[0]=='No results found':
        no_subscene.append(line)
    else:
        movies_item=etree_html.xpath('//*[@id="left"]/div/div/ul')[0].xpath('.//li')	# 获取全部li的html	这里返回的就是list ,和scrapy 有一定区别
        
        for link in movies_item:
            movies_name=link.xpath('.//div/a/text()')		# 对每个li中进行获取电影名  返回的是list
#             print(movies_name)
            if line in movies_name[0]:						# 网站会返回多个电影数据 这时候就要进行判断是否有匹配的电影
                try:
                    new_link=link.xpath('.//div/a/@href')	#如果匹配,则获取其链接
                 	content=requests.get(url="https://subscene.com"+new_link[0],headers=header) #跳转到当前电影字幕的网页
                    etree_html = etree.HTML(content.content) 
                    text = etree_html.xpath('//*[@id="content"]/div[2]/div[4]/table/tbody')[0].xpath('.//tr') #获取当前电影的全部字幕
                    for language in text:
                        text=language.xpath('.//@id')		  # 获取语言 即English等
                        try:
                            language_list.append(text[0])
                            if 'chinese' in text[0]:			 # 只要获取有中文字幕的电影
                                movies_is_exist.append(line)
                                break
                            else:
                                print(text[0])
                        except:
                            continue
                    no_subscene.append(line)
                except:
                    print(movies_name)
    
### 关于 Scrapy-Client 的使用 尽管当前提供的引用并未直接提及 `Scrapy-Client`,但从上下文中可以推测您可能希望了解如何基于 Scrapy 和其扩展工具(如 Scrapy-Redis)构建客户端应用或执行特定操作。以下是对 Scrapy 及其相关组件的深入分析。 #### 什么是 Scrapy-Client? 严格来说,“Scrapy-Client” 并不是一个官方术语或模块名称。通常情况下,开发者会通过编写脚本调用 Scrapy 命令行接口或者利用 API 来启动爬虫实例并获取数据。这种行为可被理解为一种 “客户端模式”。因此,在此场景下讨论的是如何通过命令行或其他方式运行 Scrapy 爬虫项目[^1]。 #### 如何运行一个简单的 Scrapy 脚本 假设您的目录结构类似于引用中的描述[^2]: ```plaintext example/ ├── scrapy.cfg └── example ├── __init__.py ├── items.py ├── middlewares.py ├── pipelines.py ├── settings.py └── spiders ├── __init__.py └── my_crawlspider.py/my_redisspider.py/my_rediscrawlspider.py ``` 可以通过以下命令来运行指定的 Spider 文件: ```bash scrapy runspider example/spiders/myspider_redis.py ``` 上述命令适用于单文件形式的 Spider 实现。如果已经创建了一个完整的 Scrapy 项目,则需切换到项目根目录后执行如下指令: ```bash scrapy crawl your_spider_name ``` 其中 `your_spider_name` 应替换为您实际定义的爬虫名字。 #### 配合 Scrapy-Redis 使用 当涉及到分布式爬取时,推荐采用 **Scrapy-Redis** 插件完成任务共享与去重等功能[^3]。为了启用这些特性,需要调整配置项至 `settings.py` 中[^5]: ```python # 启用 Redis 调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 设置请求指纹存储在 Redis 中 DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter' # 将所有爬过的 URL 存入 Redis 数据库中 REDIS_URL = None # 或者提供具体的连接字符串,例如 redis://localhost:6379 ``` 以上设置允许多个节点访问同一个 Redis 实例从而协同工作。 #### 自定义中间件支持 对于某些特殊需求,比如动态代理、Cookie 处理等,可通过开发自定义 Downloader Middleware 达成目的[^4]。下面展示一段基础模板代码供参考: ```python from scrapy import signals import random class RandomUserAgentMiddleware(object): def process_request(self, request, spider): ua = random.choice(['Mozilla/5.0', 'Chrome/80']) request.headers.setdefault('User-Agent', ua) def process_response(self, request, response, spider): return response def process_exception(self, request, exception, spider): pass ``` 最后记得更新 `settings.py` 添加新类路径名: ```python DOWNLOADER_MIDDLEWARES = { 'myproject.middlewares.RandomUserAgentMiddleware': 400, } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值