预备知识:在阅读本教程之前,需要对Scrapy框架有一定的了解,知晓Scrapy框架中每一个项目文件的作用。
推荐在阅读本文之前,先阅读以下这篇教程——轻松带你掌握Scrapy框架(以爬取古诗文网为例)https://blog.csdn.net/liumengqi11/article/details/112654295
CrawlSpider爬虫
- 作用:可以定义规则,让Scrapy自动的去爬取我们想要的链接。而不必跟Spider类一样,手动的yield Request。
- 创建:scrapy genspider -t crawl [爬虫名] [域名]
- 提取的两个类:
- LinkExtrator:用来定义需要爬取的url规则。
- Rule:用来定义这个url爬取后的处理方式,比如是否需要跟进,是否需要执行回调函数等。
猎云网爬虫
1.需求:实现猎云网网站的文章数据爬虫。需要保存标题、发布时间、内容、原始url字段,然后异步保存到mysql数据库中。
2.翻页链接:https://www.lieyunwang.com/latest/p1.html
3.翻页规则:Rule(LinkExtractor(allow=r’/latest/p\d+.html’), follow=True)
4.文章详情页规则:Rule(LinkExtractor(allow=r’/archives/\d+’), callback=“parse_detail”, follow=False)
5.使用twisted. enterprise.adbapi来异步的保存数据。
爬取过程
猎云网界面如下:
详情页面如下:
爬取过程:
1、新建文件搭建scrapy框架(以CrawlSpider的方式)
在命令提示符中输入以下三条命令:scrapy startproject lyw
cd lyw
scrapy genspider -t crawl lyw_spider lieyunwang.com
2、在pycharm中打开文件,在item.py中定义要爬取的字段,并在setting.py中把机器人协议设置为False,并设置user-agent,解开ITEM_PIPELINES的注释
3、在文件夹下建立run.py文件,这样运行run.py文件就相当于运行整个文件了。run.py的代码如下:
from scrapy import cmdline
cmdline.execute("scrapy crawl lyw_spider".split(" "))
4、在lwy_spider.py中修改起始url,定义提取url的规则,代码如下:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import LywItem
class LywSpiderSpider(CrawlSpider):
name = 'lyw_spider'
allowed_domains = ['lieyunwang.com']
start_urls = ['https://www.lieyunwang.com/archives/p1.html']
rules = (
Rule(LinkExtractor(allow=r'/archives/p\d+.html'), follow=True),
Rule(LinkExtractor(allow=r'/archives/\d+'), callback="parse_detail",follow=False)
)
def myprint(self,value):
print('*'*30)
print(value)
print('*'*30)
5、用xpath语法提取想要爬取的内容,但此时页码是由系统控制的,我们每次测试xpath语法时都需要爬取所有页码中的每个详情页,这样很不方便,最好是在一个详情页中测试xpath语法,都正确的话再爬取所有页面。这时需要在终端(cmd)中执行
C:\pythonProject\python爬虫\pythonProject\lyw>scrapy shell https://www.lieyunwang.com/archives/473230
,即可只在这一个url下测试xpath语法的正确性,正确后我们在把它写在pycharm中。
lwy_spider.py(爬虫文件)代码如下:
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import LywItem
class LywSpiderSpider(CrawlSpider):
name = 'lyw_spider'
allowed_domains = ['lieyunwang.com']
start_urls = ['https://www.lieyunwang.com/archives/p1.html']
rules = (
Rule(LinkExtractor(allow=r'/archives/p\d+.html'), follow=True),
Rule(LinkExtractor(allow=r'/archives/\d+'), callback="parse_detail",follow=False)
)
def myprint(self,value):
print('*'*30)
print(value)
print('*'*30)
def parse_detail(self, response):
title_list = response.xpath("//h1[@class='lyw-article-title-inner']//text()").getall()
title = "".join(title_list[2]).strip()
pub_time= "".join(title_list[1]).strip()
author = response.xpath("//a[contains(@class,'author-name')]/text()").get()
content = response.xpath("//div[@class='main-text']").get()
origin = response.url
item = LywItem(title=title,pub_time=pub_time,author=author,content=content,origin=origin)
return item
6、异步保存mysql数据
在settings结尾添加一下代码:(在这之前需要对mysql有一定了解,下载pymysql包和mysql数据库)
MYSQL_CONFIG = {
"DRIVER": "pymysql",
"HOST": "localhost",
"PORT":3306,
"USER":"root",
"PASSWORD":"******", # 这放你数据库的密码
"DATABASE":"lieyunwang" # 需要事先在mysql中建立名为leiyunwang的数据库,并在数据库中
}
pipelines.py中的代码如下:
from twisted.enterprise import adbapi
class LywPipeline(object):
def __init__(self, mysql_config):
self.dbpool = adbapi.ConnectionPool(
mysql_config['DRIVER'],
host=mysql_config['HOST'],
port=mysql_config['PORT'],
user=mysql_config['USER'],
password=mysql_config['PASSWORD'],
db=mysql_config['DATABASE'],
charset='utf8'
)
@classmethod
def from_crawler(cls, crawler):
# 只要重写了from_crawler方法,那么以后创建对象的时候,就会调用这个方法来获取pipline对象
mysql_config = crawler.settings['MYSQL_CONFIG']
return cls(mysql_config)
def process_item(self, item, spider):
# runInteraction中除了传运行sql的函数,还可以传递参数给回调函数使用
result = self.dbpool.runInteraction(self.insert_item, item)
# 如果出现了错误,会执行self.insert_error函数
result.addErrback(self.insert_error)
return item
def insert_item(self, cursor, item):
sql = "insert into lyw(title,author,pub_time,content,origin) values(%s,%s,%s,%s,%s)"
args = (item['title'], item['author'], item['pub_time'], item['content'], item['origin'])
cursor.execute(sql, args)
def insert_error(self, failure):
print("=" * 30)
print(failure)
print("=" * 30)
运行run.py文件,即可爬取数据。
爬取出的数据入下:
本教程就到这了,下面还会继续连载应用Scrapy框架的实例,希望对大家有所帮助!!!