Scrapy操作指南

详情请看

https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html

1创建项目

scrapy startproject 外层文件夹名 项目名
cd 项目名
scrapy genspider example example.com
可以看到配置文件在scrapy.cfg里

尝试连接网址:

scrapy shell url地址
# 也可以加入UA,具体方法是 scrapy shell -s USER-AGENT='' 'http://www.baidu.com'

# 然后会出现 In [1]: ,请输入以下:

response.css('div')
#会返回[<Selector xpath='descendant-or-self::div' data='<div style="display:none;">\n<script t...
'>]

response.css('div').get()
#会返回一个标签,如'<div class="ui right sidebar inverted vertical menu">Jone<\div>,其中get()会返回第一个,getall()会返回所有

response.css('div').getall()[3]
# 取得到的内容列表的第三个

response.css('div::text').get()
# 会返回一个正常的文本,如 Jone

response.css('div.::text').get()
# css选择器选择class时用. 选择id时用@

a = response.css('div.::text').get()
a.css()
# 我们也可以赋值为a,然后就转化为a.css()了

a.css('a::attr(href)').get()
# 这是a标签下的href标签值

response
# 输入response,会返回<200 https://fabiaoqing.com/bqb/lists/type/hot/page/>
response.text
# 输入response.text,会返回很长的html文本
Response.follow可以使用选择器
for href in response.css('li.next a::attr(href)'):
  yield response.follow(href, callback=self.parse)

修改后的执行命令

scrapy crawl 项目名

# 如果想将item保存下来,可以直接用-o 文件名保存到文件中,如:
scrapy crawl taobao_page -o taobao.csv
# 在[scrapy.extensions.feedexport]中会得到爬取的项目的数量

首先在settings.py文件中做一些修改

ROBOTSTXT_OBEY = False

可以使用\robots.txt找到sitemap或sitemap.xml或在bing上搜索site:www.baidu.com ext:xml

爬虫做IP池的注意事项:

# 1保存文件的方法:
from scrapy.selector import Selector
def parse(self, response):
print(response.body)
  selector = Selector(response)
  with open('ip.html', "wb") as f:
      f.write(response.text.encode('utf-8'))
      # 2使用Selector的css选择器的方法:
      ip_addr_list = selector.xpath('//table/tbody/tr')

 

    def start_requests(self):
      for i in range(5):
          time.sleep(179)
          yield scrapy.Request(url=f'https://ip.jiangxianli.com/?page=1&country=%E4%B8%AD%E5%9B%BD',
                                callback=self.parse_url, dont_filter=True)

注意:如果想多次爬取同一个网站,需要添加dont_filter=True参数,填写回调函数,回调函数用来处理后续的数据操作,凡是使用yield的都是要爬的网页名,爬取网页后一定会对数据做处理的。

如何将数据保存到数据库?

要在数据库中创建一个数据库表
create table if not exists ipTable(
ip varchar(30) NOT NULL primary key,
life_time varchar(30),
mes varchar(20),
position varchar(30),
service_provider varchar(40),
velocity varchar(30)) default charset=utf8;

然后可以试试grant all privileges on *.* to 'root'@'127.0.0.1' identified by 'mysql';
flush privileges;

要修改四个地方,一个是pipeline(连接数据库),一个是item(在处理数据的时候生成数据库表头有哪些字段),一个是爬虫文件中处理数据的函数内抓取后形成数据表中的一行完整的数据,一个是setting(开通item)

在items.py文件中写入一个数据库表的类
class IpPoolItem(scrapy.Item):
  # define the fields for your item here like:
  ip = scrapy.Field()
  mes = scrapy.Field()

在爬虫文件中形成数据表中的一行完整的数据
from ..items import IpPoolItem

service=ip_addr.xpath('td[7]/text()').extract()[0]
velocity = ip_addr.xpath('td[8]/text()').extract()[0]
life_time = ip_addr.xpath('td[9]/text()').extract()[0]
item = IpPoolItem()
item['service'] = service
item['velocity'] = velocity
item['life_time'] = life_time
yield item

在pipelines.py文件中连接数据库,凡是增删改查数据库内容的都在这里写
import pymysql

class IpPoolPipeline:
  def __init__(self):
      self.connect = pymysql.connect(host='localhost', user='root', password='mysql', db='ip_pools', port=3306)
      self.cursor = self.connect.cursor()
       
def open_spider(self, spider):
      try:
      查找数据
      sql_find = 'select * from ipTable'
          self.cursor.execute()
          self.connect.commit()
          rows = self.cursor.fetchall()
      删除数据
          sql_del = "delete from iptable where ip='"+ip+"'"
                  self.cursor.execute(sql_del)
                  self.connect.commit()
      except Exception as e:
          pass
           
  def process_item(self, item, spider):
  插入数据
      self.cursor.execute(
          'insert into ipTable(ip,mes,position,service_provider,velocity,life_time)VALUES ("{}","{}","{}","{}","{}","{}")'.format(
              item['ip'], item['mes'], item['position'], item['service_provider'], item['velocity'],
              item['life_time']))
      self.connect.commit()
      return item

  def close_spider(self, spider):
  # 关闭数据库
      self.cursor.close()
      self.connect.close()
       
在settings.py文件中注册item_pipeline可用
ITEM_PIPELINES = {
  'ip_pool.pipelines.IpPoolPipeline': 300,
}

 

日志的使用

在settings.py文件中写入以下:设置日志级别和日志路径

生成一个和spiders同级的文件夹log

import datetime

LOG_ENABLED = True
LOG_LEVEL = 'DEBUG'
now = datetime.datetime.now()
log_file_path = f'log/scrapy_{now.year}_{now.month}_{now.day}'
LOG_FILE = log_file_path

在spiders下的项目文件内加入

import logging

logging.info('这是INFO')

设置随机浏览器

在settings.py文件中去掉user_agent,然后打开DOWNLOADER_MIDDLEWARES

DOWNLOADER_MIDDLEWARES = {
  'ip_pool.middlewares.IpPoolDownloaderMiddleware': 543,
}

在middleware.py文件中写入以下:并安装fake-useragent

from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware
from fake_useragent import UserAgent

class IpPoolDownloaderMiddleware(UserAgentMiddleware):
  def process_request(self, request, spider):
      ua = UserAgent()
      request.headers['User-Agent'] = ua.random
      print(request.headers['User-Agent'])

 

设置IP池

scrapy.Request(url=f'https://ip.jiangxianli.com/?page=1&country=%E4%B8%AD%E5%9B%BD',
                                callback=self.parse_url, dont_filter=True, meta={"proxy":"http://119.101.117.163:9999"})

 

设置超时时间

DOWNLOAD_TIMEOUT = 60
DOWNLOAD_DELAY = 2
RANDOMIZE_DOWNLOAD_DELAY = True
# 增加并发
CONCURRENT_REQUESTS = 32

scrapy-splash

pip install scrapy-splash

https://github.com/scrapy-plugins/scrapy-splash

使用docker

docker pull scrapinghub/splash
sudo docker run -dit --name splash-server -p 5052:5023 -p 8050:8050 -p 8051:8051 scrapinghub/splash # 这是个举例
docker run --name splash-server -p 8050:8050 scrapinghub/splash # 上面不是要输入的,本句才是
5023(telnet)8051(https)
:前面的端口号是服务器的端口号,冒号后面的端口号是容器的端口号

docker ps -a # 查看已启动的容器
docker stop splash-server # 停止已启动的服务
#查看ip
docker inspect -f '{{.Name}} - {{.NetworkSettings.IPAddress }}' $(docker ps -aq)

curl http://172.17.0.2:8050

 

在settings.py文件中加入

SPLASH_URL = 'http://localhost:8050'

scrapy shell的使用方式:

scrapy shell
response.css('a::text').get()
# 如何退出
exit()

使用curl来操作一些内容:举例如下:

curl 'http://webapi.cninfo.com.cn/api/info/p_info3064' \
-H 'mcode: MTY0MTUzODUxNQ==' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' \
-H 'Referer: http://webapi.cninfo.com.cn/' \
--insecure
curl 'https://api.landchina.com/tGdxm/result/list' -d 'pageNum: 1' -d 'pageSize: 10' -H 'Host: api.landchina.com' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' -H 'Referer: https://www.landchina.com/' -H 'Origin: https://www.landchina.com' --insecure

 

posted @ 2022-03-07 09:21  peanut321  阅读(158)  评论(0)    收藏  举报