爬虫scrapy使用
初见scrapy
基本使用
新建项目
scrapy startproject scrapy_baidu_091
创建爬虫文件
cd startproject scrapy_baidu_091/startproject scrapy_baidu_091/spiders
scrapy genspider 爬虫名字 爬取网页(不用http)
eg. scrapy genspider baidu www.baidu.com
成功创建了baidu文件
import scrapy
class BaiduSpider(scrapy.Spider):
# 爬虫的名字 用于爬虫的时候使用的值
name = 'baidu'
# 允许访问的域名
allowed_domains = ['www.baidu.com']
# 起始url地址
start_urls = ['http://www.baidu.com/']
# 执行了起始start_urls之后执行的方法 response是返回对象
# 相当于response= urllib.request.urlopen
def parse(self, response):
print('不管下雨又刮风')
pass
运行爬虫代码
scrapy crawl 爬虫名字
eg. scrapy crawl baidu
取消robot协议
settings.py中ROBOTSTXT_OBEY = False ,或者注释掉
58同城项目
寻找url
打开58同城,F12打开控制台,打开网络,刷新,找到相应的网页
scrapy结构
项目名字
项目名字
spiders文件夹(存储爬虫文件)
init
核心功能文件
init
items 定义数据结构
middleware 中间件 代理
piplines 管道 处理下载数据
settings 配置文件
response属性与方法
response.text 字符串
response.body 二进制
response.xpath 可以直接用xpath语法
response.extract 返回selector对象的data的属性值
response.extract_first() 返回selector列表的第一个对象
汽车之家项目
后缀是html,start_urls不能加 /
scrapy工作原理
- 引擎向spiders要url
- 引擎把url给调度器
- 调度器把url放到队列中
- 从队列中取出一个请求
- 引擎将请求交给下载器
- 下载器获得互联网上的数据
- 下载器将数据返回引擎
- 引擎将数据给spiders
- spiders通过xpath获得数据或Url
- spiders将其交给引擎
- 引擎判断是数据则交给管道输出,如果是url则继续请求
scrapy shell
scrapy shell www.baidu.com
自动进入ipython
a = response.xpath('//input[@id="su"]/@value')
当当网项目
所有的selector对象都可再次调用xpath
懒加载
图片刷新到才加载src,注意换一下
yield
迭代器
如果想使用管道需要在settings里打开
# 爬虫文件执行前
def open_spider(self, spider):
# 爬虫文件执行后
def close_spider(self, spider):
多条管道同时
- 定义管道类
- 在settings中开启
如果拿不到数据要检查xpath语法是否正确
读书网项目
scrapy genspider -t crawl read https://www.dushu.com/book/1617.html
注意首页格式
数据配置
打开settings
DB_HOST = '127.0.0.1'
DB_PORT = 3306
DB_USER = 'root'
DB_PASSWORD = '12345678'
DB_NAME = 'cba_k8_test'
DB_CHARSET = 'utf8' # 注意没有杠
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
class ScrapyReadbook101Pipeline:
def __init__(self):
self.fp = open('book.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
self.fp.write(str(item))
return item
def close_spider(self, spider):
self.fp.close()
# 加载seetings文件
from scrapy.utils.project import get_project_settings
import pymysql
class MysqlPipeline:
def __init__(self):
settings = get_project_settings()
self.host = settings['DB_HOST']
self.port = settings['DB_PORT']
self.user = settings['DB_USER']
self.password = settings['DB_PASSWORD']
self.name = settings['DB_NAME']
self.charset = settings['DB_CHARSET']
self.conn = ''
self.cursor = ''
self.connect()
def connect(self):
self.conn = pymysql.connect(
host=self.host,
port=self.port,
user=self.user,
password=self.password,
db=self.name,
charset=self.charset
)
self.cursor = self.conn.cursor()
def process_item(self, item, spider):
sql = 'insert into book(name, src) values("{}", "{}")'.format(item['name'], item['src'])
# 执行与提交
self.cursor.execute(sql)
self.conn.commit()
return item
def close_spider(self, spider):
self.cursor.close()
self.conn.close()
日志文件
LOG_FILE = 'logdemo.log' # .log结尾
POST请求
def start_requests(self):
url = 'xxx'
data = {
'kw': 'final'
}
yield scrapy.FormRequest(url=url, formate=data, callback=sekf.parse_second)
def parse_second(self, response):
content = response.text