学习python网络编程很久啦,终于决定分享一些自己的经验与感悟,并且开始记录自己的学习轨迹。(本文提到的python均喂python3)
在学习使用request和urllib构建爬虫一段时间后终于发现了他们的不足:一是爬取速度确实不尽如人意,二是反复的在做一些造轮子工程,效率很低。于是开始学习scrapy框架。开始时,跟着黑马学习scrapy 感觉确实像是遇到了一门新的语言一样洪水猛兽,在经过一段时间的沉淀和反复的练习以后,很快的渡过了这一阶段,要做到也不是很难,静下心来读完本文可能就是你应该做的第一步。
好了进入今天的正题:
Scrapy爬虫爬取西刺IP
个人觉得目前讲的最为简单易懂的就是《疯狂python讲义》(百度云链接:链接: https://pan.baidu.com/s/1ZoOjW6H5W3A8m3_13nJ1hw 提取码: 2333)第20章关于scrapy的开发答题顺序:
1.定义Item类
- 开发Spider类
- 开发Pipline
当然,如果你还需要进一步设置用户代{过}{滤}理池和IP代{过}{滤}理池的话需要进一步设置Middlewares(通常都会需要,今天先不会提到)
当然还不清楚scrapy各个模块功能的同学可以选择先去这里看看Scrapy各个模块的介绍
为了操作的连续性我会从头至尾的记录所有过程,有一定scrapy基础可以跳过这一部分
cmd命令运行:
scrapy startproject xcdlspider
点击进入生成的xcspider文件在与scrapy.cfg同级的目录下打开cmd(shift+右键 后点击在此处打开powershell窗口)命令运行:
scrapy genspider xcspider xicidaili.com
后面的操作建议在pycharm中进行,主要是方便快捷
接下来的解释具体看代码行中的注释
1.定义Item类(-items.py-)
import scrapy
class XcdlspiderItem(scrapy.Item):
#IP节点
IP_address = scrapy.Field()
#端口
port = scrapy.Field()
#服务器地址
server_address = scrapy.Field()
#是否匿名
anonymous_sit = scrapy.Field()
#类型
Type = scrapy.Field()
#速度
speed = scrapy.Field()
#连接时间
conect_time = scrapy.Field()
#存活时间
alive_time = scrapy.Field()
#验证时间
Ver_time = scrapy.Field()
2.开发Spider类(-xcspider.py-)
# -*- coding: utf-8 -*-
import scrapy
from xcdlspider.items import XcdlspiderItem
#从创建的xcdlspider的item中import XcdlspiderItem类
class XcspiderSpider(scrapy.Spider):
name = 'xcspider'#爬虫名称
allowed_domains = ['xicidaili.com']#限制爬虫的范围
start_urls = ['https://www.xicidaili.com/nn']#爬虫开始爬取的链接地址
def parse(self, response):
#便利西刺的所有节点
item = XcdlspiderItem()
#初始化item对象一定要加括号,很多人在开发这里的时候都会采坑
#西刺的网页源代码与chrome加载过的源代码结果不同,最终处理的是我们在网页上点击“查看网页源代码”的结果然后使用xpath处理
#xpath个人认为是最为好用的选择方式,没有之一,可以着重学习下,其实不是很难10分钟搞定
port_cells = response.xpath('//*[@id="ip_list"]/tr')
for port_cell in port_cells:
#接下来就是使用xpath提取你所需要的信息
item['IP_address'] = port_cell.xpath('./td[2]/text()').extract()
item['port'] = port_cell.xpath('./td[3]/text()').extract()
item['server_address'] = port_cell.xpath('./td[4]/a/text()').extract()
item['anonymous_sit'] = port_cell.xpath('./td[5]/text()').extract()
item['Type'] = port_cell.xpath('./td[6]/text()').extract()
item['speed'] = port_cell.xpath('./td[7]/div/@title').extract()
item['conect_time'] = port_cell.xpath('./td[8]/div/@title').extract()
item['alive_time'] = port_cell.xpath('./td[9]/text()').extract()
item['Ver_time'] = port_cell.xpath('./td[10]/text()').extract()
#返回item内容,这里一定要使用yield
yield item
#返回item内容,这里一定要使用yield
#爬取按钮“下一页”的地址,传给scrapy处理实现迭代
new_links = response.xpath('//*[@class="next_page"]/@href').extract()
if new_links and len(new_links) > 0:
# 获取下一页的链接
new_link = new_links[0]
# 再次发送请求获取下一页数据https://www.xicidaili.com构建url
yield scrapy.Request("https://www.xicidaili.com" + new_link, callback=self.parse)
3.开发Pipline(-piplines.py-)
用于处理爬取到的数据,我们这里生成json格式的数据
# -*- coding: utf-8 -*-
import json
class XcdlspiderPipeline(object):
def __init__(self):
self.json_file = open("job_positions.json", "wb+")
self.json_file.write('[\n'.encode("utf-8"))
# 重写close_spider回调方法,用于关闭文件
def close_spider(self, spider):
print('----------关闭文件-----------')
# 后退2个字符,也就是去掉最后一条记录之后的换行符和逗号
self.json_file.seek(-2, 1)
self.json_file.write('\n]'.encode("utf-8"))
self.json_file.close()
def process_item(self, item, spider):
print('ip地址:\t',item['IP_address'])
# 将item转换成JSON字符串
text = json.dumps(dict(item), ensure_ascii=False) + ",\n"
# 写入JSON字符串
self.json_file.write(text.encode("utf-8"))
我们的开发完成了吗?
当然没有,还有最后一步:修改setting设置
这里需要着重注意,西刺有一定的反爬虫措施,所以我们需要伪造user-agent
修改-settings.py-
你需要做的是找到一下两部分删除掉他们的注释,并且将下面的USER_AGENT后面的参数改为自己浏览器的参数(如何获取自己浏览器的参数,大家可以自行google)
- 第一部分:修改DEFAULT_REQUEST_HEADERS
DEFAULT_REQUEST_HEADERS = {
'USER_AGENT' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,applicati',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
- 第二部分:修改ITEM_PIPELINES
ITEM_PIPELINES = {
'xcdlspider.pipelines.XcdlspiderPipeline': 300,
}
#以及机器人协议,由于我们在练习所以先不遵守
ROBOTSTXT_OBEY = False
至于这一部分为什么这样做,暂时不需要懂,可能会让我们思维混乱,后面我会继续提到的。
接下来就是运行
还是在xcdlspider目录打开cmd
命令行:
scrapy crawl xcspider
这一步可能会出现错误,需要大家结合自己的经验去分析,然后搜索答案。
代码运行结果:
写在最后:学习这么长时间的编程,发现它带给我自己的,除了不断学习的能力,还有面对困难时敢于出发去寻找解决方案的勇气。始终坚信,我不是第一个遇到这样问题的人,当然也不是最后一个。
献丑了各位第一次,谢谢大家的耐心阅读,最后附上源码,我会尽力回复大家的问题
注:个人的csdn同步https://blog.csdn.net/weixin_43745588/article/details/99120820