十三周内容笔记

day37

01-selenium相关配置

封装到一起用的时候调用就可以了,很方便。

def self_options():

op = webdriver.ChromeOptions()

# 1. 设置selenium不自动关闭浏览器

op.add_experimental_option("detach", True)

# 2. 不加载网页图片,提升网页加载速度

op.add_argument('blink-settings=imagesEnabled=false')

# 3. 避免终端下执行代码报错

op.add_experimental_option("excludeSwitches", ['enable-automation', 'enable-logging'])

# 4. 为selenium设置请求头UA,selenium调用的浏览器自带UA,但是因为存在UA反爬,所以可以选择性是否添加

UA = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36'

op.add_argument(f"--user-agent={UA}")

# 5. 设置代理IP

# proxy_ip = '127.0.0.1:8000'

# op.add_argument(f'--proxy-server=http://{proxy_ip}')

# 6. 加载拓展插件

op.add_extension('./FeHelper.crx')

# 7. 加载用户缓存,可以记录使用记录和cookie,如果不指定缓存路径,会自动创建临时文件夹。

# user_dir = r'./browser_cache'

# op.add_argument(f"--user-data-dir={user_dir}")

# 8. 无头浏览器:提升网页访问速度,但是牺牲的是增加更多的反爬风险,如果涉及到与网页的交互,有些网站就不能使用无头模式。

op.add_argument('--headless')

return op

02-selenium窗口尺寸对爬虫的影响

如果窗口过小,会导致selenium无法实现下一步的操作,页面上不显示,自然就无法找到对应的位置进行交互,会返回element click intercepted

element click intercepted:有些网站有检测机制,页面元素未显示在用户视野中(网页显示区域)时,元素不允许进行交互。

browser.maximize_window():窗口最大化

03-爬虫蜜罐

蜜罐:形容抵不住诱惑,之前在学习网安的时候了解到过。爬虫蜜罐即爬虫陷阱。

一、概述

一个接入了互联网的网站,只要能和外部产生通信,就有可能被黑客攻击。所以有些网站设置了一些陷阱,来引诱攻击者从而达到自身不被攻击的目的。

二、蜜罐分类

电子邮件蜜罐:邮箱管理者会在网络中故意放出一些邮箱账号,这些账号只能被扫描器发现,正常人发现不了,所以如果这些账号接收到邮件,就可以将发件地址标记为恶意账号。

数据库蜜罐:用来监控攻击者对数据库的攻击命令或发现利用sql注入攻击,运营人员就可以将访问数据区的ip地址拉黑。

爬虫蜜罐:例如:在网页源码中注释掉一些链接,这些链接普通用户永远不会看到,但是写爬虫的人能看到,爬虫能访问到,如果有爬虫访问了这些注释掉的陷阱链接,立刻能够检测到是哪个ip地址访问了,直接将此ip拉黑。

三、蜜罐的优缺点

优点:节省资源、能够轻易捕捉到危险、准确率高。

缺点:准确率高不等于100%,有误封的缺点。

day38

scrapy爬虫框架

一、scrapy爬虫框架介绍

scrapy是基于python开发的爬虫框架,用于从网站中抓取数据。python爬虫领域中scrapy是最强悍的框架。该框架提供了非常多的爬虫相关的基础组件,建构清晰,可拓展性强。

二、scrapy爬虫框架出现的条件

每次写爬虫都需要写一遍重复性的内容,scrapy作者就根据重复性的内容封装成通用的代码,通过多版本迭代,住家形成规模庞大的框架。

三、安装

pip install scrapy

四、创建scrapy爬虫项目

命令:scrapy startproject 项目名

创建中国新闻网爬虫项目:scrapy startproject ChinaNews

创建完是这样式儿的:

后面会对上面的文件展开操作

五、开始操作

先使用cd命令切换进项目,通过命令初始化某个网站的爬虫文件

scrapy genspider 文件名(运行scrapy项目时的名字)被爬取网站的链接

scrapy genspider NewsSpider https://www.chinanews.com.cn/

六、scrapy爬虫项目的运行

scrapy crawl 爬虫名字

scrapy crawl NewsSpider

七、settings.py(很重要)

这是scrapy的配置文件,需要修改成不遵循robots协议:ROBOTSTXT_OBEY = False

八、多线程(默认16线程):

day39

对中国新闻网即时新闻精选进行实操

一、在NewsSpider.py文件内写爬虫代码

import scrapy

from ..items import ChinanewsItem

class NewsspiderSpider(scrapy.Spider):

name = "NewsSpider"

allowed_domains = ["www.chinanews.com.cn"]

start_urls = ["https://www.chinanews.com.cn/"]

def parse(self, response):

# response:网页的响应结果

# 查看网页源代码

# print(response.text)

# css方法:scrapy提供了css方法能够使用css选择器定位到元素

# 如果要取标签属性,需要在css方法的css选择器中这样写 --> 标签::attr(属性名)

# get():获取到css选择器指定的内容

link = response.css('body > div:nth-child(9) > div.news-right > div.top-jsxw > div.jsxw-title.lmtitle > a::attr(href)').get()

# print(link)

# 将链接补全

new_link = self.start_urls[0] + link[1:]

# print(new_link)

# 构建10页链接

for page in range(1, 11):

page_link = new_link.replace('1', str(page))

# print(page_link)

# scrapy.Request():scrapy中负责请求链接的方法

# callback:回调函数,可以提前调用一个不存在的函数、变量等,然后紧接着再去创建。

yield scrapy.Request(url=page_link, callback=self.NewsInfo)

# Xpath写法

def NewsInfo(self, response):

# 实例化实体类

newsItem = ChinanewsItem()

# 此时response根节点时html

li_list = response.xpath('/html/body/div[4]/div[1]/div[2]/ul/li')

for i in li_list:

if i.xpath('./@class').get() != 'nocontent':

news_type = i.xpath('./div[1]/a/text()').get()

news_title = i.xpath('./div[2]/a/text()').get()

news_link = 'https://www.chinanews.com.cn' + i.xpath('./div[2]/a/@href').get()

news_time = i.xpath('./div[3]/text()').get()

# print(news_type, news_title, news_link, news_time)

newsItem['NewsType'] = news_type

newsItem['NewsTitle'] = news_title

newsItem['NewsLink'] = news_link

newsItem['NewsTime'] = news_time

yield newsItem

还有CSS写法,不过我不太喜欢CSS,看起来代码太臃肿。

# CSS选择器写法

def NewsInfo(self, response):

# 从响应结果中查看访问的是哪个链接

# print(response.url)

# 获取当前页面的所有新闻的li标签

li_list = response.css('body > div.w1280.mt20 > div.content-left > div.content_list > ul > li')

# print(li_list)

for i in li_list:

# 如果要取标签内容,需要在css方法的css选择器中这样写 --> 标签::text

news_type = i.css('li > div.dd_lm > a::text').get()

# 如果li的class属性为nocontent,即值为空,则去掉此li标签

if news_type != None:

news_title = i.css('li > div.dd_bt > a::text').get()

news_link = 'https://www.chinanews.com.cn' + i.css('li > div.dd_bt > a::attr(href)').get()

news_time = i.css('li > div.dd_time::text').get()

print(news_type, news_title, news_link, news_time)

newsItem['NewsType'] = news_type

newsItem['NewsTitle'] = news_title

newsItem['NewsLink'] = news_link

newsItem['NewsTime'] = news_time

yield newsItem

二、在items.py文件内实体化

import scrapy

class ChinanewsItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

# 此处写什么代码取决于你提取了哪些信息

NewsType = scrapy.Field()

NewsTitle = scrapy.Field()

NewsLink = scrapy.Field()

NewsTime = scrapy.Field()

# Field()是获取scrapy提供的Item类(实体类)中的信息

# 爬虫主要目标就是从非结构化数据源中提取出结构化的数据

# 结构化数据一般是一个字段对应一个或一类数据,这种情况下字典是最好用的

# 但是字典很容易将键的名字写错,此时scrapy的Item类起作用了,Item类本身就是处理结构化数据的

# 将字段名化为变量名使用,就不会出错了。

三、数据存储,在piplines.py内操作

import csv

# scrapy 的数据存储有两种形式

# 方式一:直接使用命令存储文件

# scrapy crawl 爬虫名字 -o 文件名.拓展名

# 或者 scrapy crawl 爬虫名字 --output 文件名.拓展名

# 使用命令的形式存储数据,拓展名支持8种类型的文件

# json、jsonlines、jsonl、jl、csv、xml、marshal、pickel(python 高性能文件)

# scrapy crawl NewsSpider -o data.csv

# 方式二:手写代码实现数据的存储

# 注意:管道中的代码想要执行,必须告知scrapy,我添加了什么代码

class ChinanewsPipeline:

def process_item(self, item, spider):

return item

class ChinanewsToCsvPipline:

def open_spider(self, spider):

"""当爬虫开始执行时,open_spider被执行"""

self.file = open('数据.csv', 'w', encoding='utf-8', newline='')

csv.writer(self.file).writerow(['新闻类型', '新闻标题', '新闻链接', '发布时间'])

def process_item(self, item, spider):

"""爬虫执行过程中执行的代码"""

data = [item['NewsType'], item['NewsTitle'], item['NewsLink'], item['NewsTime']]

csv.writer(self.file).writerow(data)

return item

def close_spider(self, spider):

"""当爬虫结束执行时,close_spider被执行"""

self.file.close()

管道中的代码想要执行,必须告知scrapy,我添加了什么代码,在settings.py中操作

# 字典中的键是管道中需要执行的代码,对应的数值是执行的先后顺序,范围[0, 1000]

# 数值越小,优先级越高

ITEM_PIPELINES = {

# "ChinaNews.pipelines.ChinanewsPipeline": 300,

"ChinaNews.pipelines.ChinanewsToCsvPipline": 300,

}

四、UA反反爬的设置

在middlewares.py文件中操作,添加如下类

class ChinanewsUserAgentDownloaderMiddleware:

def __init__(self):

file = open('UserAgent.txt', 'r')

self.UAList = ast.literal_eval(file.read())

@classmethod

def from_crawler(cls, crawler):

"""在爬虫开始或结束时进行一些操作的函数"""

# This method is used by Scrapy to create your spiders.

s = cls()

crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)

return s

def process_request(self, request, spider):

"""下载器发送请求前针对请求的处理"""

# 将一个UA放入到请求的headers中

request.headers['User-Agent'] = random.choice(self.UAList)

return None

def process_response(self, request, response, spider):

"""下载器请求完页面,和引擎通信时对响应结果做的处理"""

return response

def process_exception(self, request, exception, spider):

"""如果出现异常,怎么处理"""

pass

def spider_opened(self, spider):

"""日志信息处理"""

spider.logger.info("Spider opened: %s" % spider.name)

同样需要告诉scrapy我添加了什么代码

DOWNLOADER_MIDDLEWARES = {

# "ChinaNews.middlewares.ChinanewsDownloaderMiddleware": 543,

"ChinaNews.middlewares.ChinanewsUserAgentDownloaderMiddleware": 100,

}

这玩意儿是真有点抽象,要完全理解需要时间的,不过我觉得现在刚刚起步,不着急理解的,先依葫芦画瓢当个工具使用就就可以,毕竟用工具的时候不会有人会去完全弄清楚原理吧哈哈。

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: