Python之scrapy使用教程
来源:互联网 发布:热血江湖自动登录源码 编辑:程序博客网 时间:2024/05/20 05:29
scrapy抓取西刺代理并用Excel保存
- (一)解析网站结构
- ①,首先浏览器访问西刺代理首页:西刺免费代理IP
②,对查看网页源代码,对网页结构有初步的了解
③,因为我们使用的是 scrapy 来抓取内容。所以,我们可以先使用 scrapy shell 来模拟下scrapy的访问。cmd 中输入
>>> scrapy shell "http://www.xicidaili.com/"
我们发现运行之后返回的states状态码是 503,出现了服务器内部问题。其实不然,是因为服务器将我们识别后拒绝了。解决方法:添加 USER_AGENT 信息。>>> scrapy shell -s USER_AGENT="浏览器的User-Agent信息" "http://www.xicidaili.com/"
⑤,完成 ③ 步骤之后,便可以对该网站进行相关的调试了
- (二)代码编写
- 首先根据网站结构确定我们的需求:
“IP地址”, “端口”, “服务器地址”, “匿名”, “类型”, “速度”, “连接时间”, “存活时间”, “验证时间”
然后正真进入代码编写: ①,编写 items :
class IpItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() ip_address = scrapy.Field() port = scrapy.Field() server_address = scrapy.Field() hiding = scrapy.Field() kind = scrapy.Field() speed = scrapy.Field() connect_time = scrapy.Field() alive_time = scrapy.Field()
- ②,编写爬虫spider
- 这里对spider中间一些信息的处理可能比较难理解,如果没有了解到 openpyxl 表格操作的话,不过我这里做了大量的注释,相信还可以让大家了解到一些关于 openpyxl 的一些简单操作。
需要注意的是,因为每次返回的是网页的一行tr内容,所以在处理时 记得进行内容的拷贝。不然每次都会别后面一次内容覆盖掉。
# -*- coding: utf-8 -*-import scrapyfrom IP.items import IpItemclass ProxySpider(scrapy.Spider): name = 'Proxy' allowed_domains = ['xici.com'] start_urls = ['http://xici.com/'] def start_requests(self): for page in range(1,11): yield scrapy.Request("http://www.xicidaili.com/nn/%d"%page) # 每次生成一个Request, 返回一页的内容 # 函数返回:一页的内容。但是每次pipeline处理其中的一行 def parse(self, response): item = IpItem() items = {} table_ip_list = response.xpath('//table[@id="ip_list"]')[0] # 获取第一个table的 selector 选择器 trs = table_ip_list.xpath('//tr') #获取每一行 选择器对象可以使用 xpath 操作 再得到选择器对象 # 第一行信息标题信息不用采集 for tr in trs[2:]: row = trs.index(tr) # 增加索引,方便表格操作 item["ip_address"] = tr.xpath('td[2]/text()').extract()[0] item['port'] = int(tr.xpath('td[3]/text()').extract()[0]) # port 设为数字 if len(tr.xpath('td[4]/a/text()').extract()) is 0: item['server_address'] = '未知' # 如果该栏为空,则填未知 else: item['server_address'] = tr.xpath('td[4]/a/text()').extract()[0] item['hiding'] = tr.xpath('td[5]/text()').extract()[0] item['kind'] = tr.xpath('td[6]/text()').extract()[0] item['speed'] = tr.xpath('td[7]/div/@title').extract()[0] item['connect_time'] = tr.xpath('td[8]/div/@title').extract()[0] item['alive_time'] = tr.xpath('td[9]/text()').extract()[0] item['check_time'] = tr.xpath('td[10]/text()').extract()[0] item_copy = item.copy() # 这里一定要对item进行拷贝,光是赋值的话会被覆盖 items[row] = item_copy # 通过建立字典方便在pipeline中来确定行数 # 如:{row:{"key":"value"}}形式 row为在表格中需要保存的行数 # 每次以一行数据为单位被处理 return items
- ②,编写pipeline处理item并保存到.xlsx文件
- 在编写这个pipeline时,我反复的调试,发现一些传进来的信息格式是这样的。比如我们在spider每次处理item 的格式为:{row:{“key”:”value”}} 形式,然后把他一次更新到自己定义的items 中,最后执行return语句。安装常理来说,传递给pipeline也应该是包含跟多个item 字典类型的字典,那么我们在pipeline处理的时候也应该通过迭代获取每一个单独的item。
然而,事实并非如此。而是每次传进pipeline的都是单独的一个item 所以我们在pipeline中处理item参数是不能使用迭代。而是直接对 item 参数进行相关操作。
我想着应该是 scrapy 本身机制问题。你每往Item这个类进行一次数据传递的时候,都会被记忆,然后再传递给pipeline是会自动帮你迭代处理好数据。
这只是我的个人理解。毕竟官方文档中,只是说spider会把返回的item传递给pipeline 把 Request 传递给调度器。
# -*- coding: utf-8 -*-# Define your item pipelines here## Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlfrom openpyxl import Workbook, load_workbookfrom openpyxl.styles import colors, Alignment, Fontimport os.path# 每获得一页内容,建立一张新的sheet表格# 第一次创建时,选择第一个 sheetclass IpPipeline(object): def process_item(self, item, spider): # 实例化一个workbook对象 if os.path.exists("Proxy.xlsx"): wb = load_workbook("Proxy.xlsx") ws1 = wb.create_sheet() # 建立一张表 else: wb = Workbook() ws1 = wb.active # 每次保存一行数据 for row in item: # 保存第一列的 IP ws1.cell(row=row, column=1, value=item[row]["ip_address"]) # 保存第二列的端口 port ws1.cell(row=row, column=2, value = item[row]["port"]) # 保存第三列的服务器地址 server_address ws1.cell(row=row, column=3, value = item[row]["server_address"]) # 保存第四列的匿名情况 hiding ws1.cell(row=row, column=4, value = item[row]["hiding"]) # 保存第五列的协议类型 kind ws1.cell(row=row, column=5, value = item[row]["kind"]) # 保存第六列的网络速度 speed ws1.cell(row=row, column=6, value = item[row]["speed"]) # 保存第七列的连接速度 connect_time ws1.cell(row=row, column=7, value = item[row]["connect_time"]) # 保存第八列的存活时间 alive_time ws1.cell(row=row, column=8, value = item[row]["alive_time"]) # 保存第九列的验证时间 check_time ws1.cell(row=row, column=9, value = item[row]["check_time"]) # 对工作簿样式进行处理 self.process_excel(work_book=wb, work_sheet=ws1) # 保存工作簿 wb.save('Proxy.xlsx') return item # 更改表格样式 # 传入参数 工作簿对象wb, 表格对象ws1 def process_excel(self, work_book, work_sheet): # 添加第一行 first_row = ("IP地址", "端口", "服务器地址", "匿名", "类型", "速度", "连接时间", "存活时间", "验证时间") for col in range(1, len(first_row)+1): work_sheet.cell(row=1, column=col, value=first_row[col - 1]) work_sheet.title = "代理页" row_length = work_sheet.max_row # 获得包含数据的总行数int sheet.rows 返回所有行(含数据)可用来迭代 col_length = work_sheet.max_column # 获取总列数 work_sheet.sheet_properties.tabColor = "1072BA" # sheet背景颜色 # 设置列宽 work_sheet.column_dimensions['A'].width = 22 work_sheet.column_dimensions['C'].width = 20 work_sheet.column_dimensions['F'].width = 16 work_sheet.column_dimensions['G'].width = 16 work_sheet.column_dimensions['H'].width = 16 work_sheet.column_dimensions['I'].width = 20 # 设置行高 for row in range(0, row_length): work_sheet.row_dimensions[row+2].height = 20 # 设置第一行的单元格样式 居中,字体,颜色 # 按列迭代 for col in work_sheet.iter_cols(min_row=1, max_row=1, min_col=1,max_col=col_length): for cell in col: cell.alignment = Alignment(horizontal="center", vertical="center",) cell.font = Font(size=16, color="CD2626", bold=True, italic=False) # 加粗 倾斜 # 设置其他子元素格式 # 按行迭代 for row in work_sheet.iter_rows(min_col=1, min_row=2, max_col=col_length, max_row=row_length): # row 为一行的tuple对象 for cell in row: cell.alignment = Alignment(horizontal="center", vertical="center") cell.font = Font(size=12, color="CD6090", bold=True, italic=False) work_book.save('Proxy.xlsx')if __name__=="__main__": # 用来此时本文件,避免每次都要运行整个儿scrapy a = IpPipeline() a.process_item(item={},spider=None) # 主要用来测试相关表格操作是否合适
- ③,中间件MIDDLEWARES
middlerwares 的编写其实也简单。分为两类,downloadermiddleware & spidermiddleware 。而我们常用的主要是是前者。下载器中间件。我们可以通过它来设置代理IP池和User-Agent池来防止爬虫被网站BAN。
每个中间件都需要继承相应的类,这些类都包含以下一个或多个方法:
①:process_request(request, spider) 方法
②:process_response(request, response, spider) 方法
③:process_exception(request, exception, spider) 方法
分别用来处理请求的request,返回的response,以及跳出的异常。具体步骤:
①,在自己工程的根目录新建一个 mymiddlewares.py 文件,我们在这里面编写middleware内容。
②,编写代理IP中间件:
# coding : utf-8from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddlewareimport randompool = [ {"ip":"121.31.156.251:8123"}, {"ip":"106.57.6.218:4326"}, {"ip":"61.135.217.7:80"},]# 用户代理池的中间件class IPPOOLS(HttpProxyMiddleware): def process_request(self, request, spider): ip = random.choice(pool) #print("当前使用的IP是:%s" % ('http://'+ip["ip"])) # 将IP添加到request request.meta["proxy"] = 'http://'+ip["ip"] return None
: ②,编写User-Agent中间件:
from scrapy.downloadermiddlewares.useragent import UserAgentMiddlewarefrom user_agent.base import generate_user_agent# 用户header池的中间件class AGENTPOOLS(UserAgentMiddleware): ''' def __init__(self, user_agent=''): self.user_agent = user_agent ''' def process_request(self, request, spider): user_agent = generate_user_agent() print("这一次使用的是 %s" % user_agent) request.headers.setdefault(b'User-Agent', user_agent)
他们都继承了自己的类,然后我们通过重写里面的方法就能实现制定功能。
- (三)激活设置
- 写了这么多,接下来当然是激活我们改写的东西。进入settings.py,添加自己相应的pipeline,middleware,.etc。然后就可以了。
关于这一块我觉得挺简单的。只需要把相应的注释符 # 去掉就可以了。 - (四)运行效果图
有朋友可能说为什么不采用直接保存到.csv 文件,这里纯属个人爱好。方便处理一点这个。
好了,就到这了希望可以帮到需要的朋友。^_^
- Python之scrapy使用教程
- Python爬虫之Scrapy安装教程
- Python:Scrapy Shell的使用教程
- python+scrapy安装教程
- python+scrapy安装教程
- python爬虫之Scrapy 使用代理配置
- python爬虫之Scrapy 使用代理配置
- python学习之Mac安装Scrapy指南教程
- scrapy安装使用教程
- python爬虫之Scrapy
- scrapy-redis集成scrapy-splash使用教程
- python scrapy使用
- Python爬虫系列之----Scrapy(七)使用IP代理池
- Python之Scrapy爬虫框架安装及简单使用
- Scrapy Shell的使用教程
- 学习python之走进Scrapy
- Python Scrapy实例之NumKr
- Python之Scrapy程序运用
- 主流嵌入式开源GUI比较
- nfs速度优化
- 模块API之try_module_get
- asdsadas
- 接口测试学习总结
- Python之scrapy使用教程
- PEID加密算法识别插件Krypto ANALyzer
- hadoop实现wordcount的三种方法
- 状态保持
- 吴恩达【深度学习工程师】学习笔记(六)
- Bootstrap学习笔记 10
- 我理解的java流基础篇(四)
- Linux操作系统 第四次实验-Linux系统管理
- 定时器触发时间设置学习