爬虫

bs4

aa = bs('r','lxml')
div = aa.find('div',class_="values").text
li = aa.select(".classname > ul > li ")

xpath

from lxml import etree
tree = etree.HTML("page")
tree.xpath('/html/head/meta') 最左侧的/表示从根标签开始定位,非最左侧的/表示一个层级
tree.xpath('/html//meta') 非最左侧的//表示多个层级
tree.xpath('//head/meta') 最左侧的//表示从任意位置开始定位

定位标签:
    tree.xpath('//div[@class="valus"]/p')
索引定位:tag[index]:索引从1开始

取文本: 
    /text() 直系文本内容  tree.xpath('//div[@class=""]/p[1]/text()')
    //text() 所有文本内容
取属性:
    /@attrname 返回属性内容

局部解析:
    li_list = tree.xpath('//div[@class="slist"]/ul/li') 获取所有li
    for li in li_list:
        li.xpath('./a/img/@src') 进行局部解析,获取img的src
        li.xpath('./a/text()) 局部解析,获取a的文本

    

cookie

自动处理:基于Session对象
获取一个Session对象:requests.Session()返回一个Session对象
Session对象的作用:
该对象可以像requests一样调用get和post发起指定的请求。在使用Session发请求的过程中,如果产生了Cookie,则cookie会被自动存储到该Session对象中,下次再次使用Session对象发起请求,刚该次请求就是携带cookie进行的请求发送。

验证码: 使用打码平台,
先从页面获取验证码图片,保存到本地,然后使用打码平台返回值。

    如果请求参数中有乱序的参数,最好验证一下此参数是不是动态变化的
        一般来说,动态变化的请求参数会被隐藏在前台页面中,需要去前面页面源码中 找
        如果前台页面没有,可以基于抓包工具进行进行全局搜索

异步爬虫

from multiprocessing.dummy import Pool
pool =Pool(3) 开启3个线程
使用get_request 作为回调函数,需要基于异步的形式对urls列表中的每一个列表元素进行操作,
保证回调函数必须要有一个参数和返回返回值
result_list = pool.map(get_request,urls)
pool.map(pars,result_list) 解析 的回调
print(result_list)

selenium

scrapy

import scrapy

  • 创建工程:cd ProName
    • scrapy startproject ProName
    • 目录结构:
      • spiders:爬虫文件夹
        • 必须要存放一个爬虫文件
      • setting.py:工程的配置文件
  • 创建爬虫源文件:
    • scrapy genspider spidername www.xxx.com
    • 编写对应的代码在爬虫文件中
  • 执行工程
    • scrapy crawl spidername
    • 执行工程后,默认会输出工程所有的日志信息
    • 指定类型日志的输出:
      • setting.py:LOG_LEVEL = 'ERROR'

爬虫文件spiderName内容:
- name: 爬虫文件名称,该文件的唯一标识
- start_urls:起始url列表,存储的都是url,url可以被自动进行get请求
- parse方法: 请求后的数据解析操作
settings.py:
1.禁止robots ROBOTS_OBEY = False
2.指定日志类型:LOG_LEVEL = 'ERROR'
3.UA伪装

scrapy 数据解析
article_list = response.xpath() #xpath 和etree里的有区别
此处xpath返回的列表中存储的不时字符串,而是Selector对象,字符串数据在Selector中
需要使用extract()将data属性值取出,extract_first()将列表中第一个列表元素表示的Selector对象的data值取出
title = article.xpath('./div/[1]/h1/a/text()').extract_first()

持久化存储

- 基于终端指令的持久化存储
要求:只可以将parse返回值 存储到本地指定后缀的文本文件中
执行指令:scrapy crawl spiderName -o filepath
- 基于管道的持久化存储(重点)
- 在掉文件中进行数据解析
- 在items.py中定义相关属性
- 在解析出的数据中有几个数据,就要定义几个属性
- title = scrapy.Field()
- 在掉文件中将解析到的数据存储封闭到Item类型的对象中
- 将Item类型对象提交给管道
- 在管理文件(pipelines.py)中,接收掉文件提交过来的Item类型对象,且对其进行任意形式的换货存储操作
- 在配置文件中开启管道机制
ITEM_PIPELINES={'WANG.pipelines.wanline':300, }#300是优先级,数越小,优先级越高,自己写的类如mysql等,要加入到这里
- item 只会将数据提交给优先级最高的管道类
- 优先级高的管道类,需要return item,将item返回给下一个优先级的管道类

class FirstSpider(scrapy.Spider):
name = 'First'
allowed_domains = ['www.xxx.com']
start_urls = ['https://www.baidu.com/','https://www.taobao.com/'] #列表中存储的URL都会被进行get请求的发送

def parse(self, response):
    title = article.xpath('./div/[1]/h1/a/text()').extract_first()
    item = WangziproItem()
    item['title'] = title
    #将item提交给管道:
    yield item

管道文件--pipelinies.py :
import pymysql
from redis import Redis

class wanPipeline(object):
fp = None
#重写父类的两个函数
def open_spider(self,spider):
#只在爬虫开始的时候打开一次)
self.fp = open('duanzi.txt','w',encoding='utf-8')
def close_spider(self,spider):
#只在爬虫结束时执行一次
self.fp.close()

def process_item(self,item,spider):
    self.fp.write(item['title']+':'+item['content']+'\n')
    将数据写入本地文件
    yield item

#将数据存到Mysql中:
class MysqlPipeline(object):
conn = None
cursor = None
#定义打开数据库的函数
def open_spider(self,spider):
self.conn = pymysql.Connect(host='127.0.0.1',port=3306,......)
print(self.conn)
def process_item(self,item,spider):
self.cursor = self.conn.cursor()
sql = 'insert into duziwnag values ("%s","%s")'%(item['title'],item['connect'])

    #事物处理
    try:
        self.cursor.execute(sql)
        self.conn.commit()
    except Exception as e:
        print(e)
        self.conn.rollback()
    return item # 在多管道,本管道优先级高的情况下加上
#定义关闭数据库
def close_spider(self,spider)
    self.cursor.close()
    self.conn.close()

#将数据存储到 redis

class Redispipeline(object):
conn = None
def open_spider(self,spider):
self.conn = Redis(host='127.0.0.1',port=6379)
def process_item(self,item,spider):
#报错:将Redis 模块的版本指定成2.10.6,pip install -U redis==2.10.6
self.conn.lpush('duanziData',item)

posted on 2022-10-26 10:19  秋不语  阅读(224)  评论(0)    收藏  举报

导航