关于Scrapy框架的使用,不再详细说明。
爬虫的工程文件里面有几个特别重要的py文件:
spider.py 决定如何取爬取什么网页
items.py 决定爬取哪些项目
pipelines.py 决定爬取的内容怎么处理
settings.py 决定由谁去爬取
因此,spider.py文件的代码如下:
import scrapy
from douban_movie.MovieItem import DoubanMovieItem
class DoubanSpider(scrapy.Spider):
name = 'douban' ------spider的名字
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
# 实例一个容器保存爬取的信息
item = DoubanMovieItem()
# 这部分是爬取部分,使用xpath的方式选择信息,具体方法根据网页结构而定
for box in response.xpath('//ol[@class="grid_view"]/li'):
item['Rank']=box.xpath('.//div[@class="pic"]/em/text()').extract()[0]
item['Name']=box.xpath('.//div[@class="info"]/div[1]/a/span[1]/text()').extract()[0].strip().replace("\n","").replace(" ","")
s=box.xpath('.//div[@class="bd"]/p/text()').extract()[0].strip().replace(" ","")
item['Author'] =s.split()[0]
if len(s.split())>1:
item['Actor'] = s.split()[1]
item['Score']=box.xpath('.//div[@class="star"]/span[2]/text()').extract()[0].strip()
item['Introduction']=box.xpath('.//p[@class="quote"]/span/text()').extract()[0].strip().replace('\n','').replace(' ','')
item['Url']=box.xpath('.//div[@class="pic"]/a/@href').extract()
yield item
# url跟进开始
# 获取下一页的rl信息
next_url = response.xpath('//span[@class="next"]/link/@href').extract()
if next_url:
# 将信息组合成下一页的url
page = 'https://movie.douban.com/top250'+next_url[0]
yield scrapy.Request(page, callback=self.parse)
说明下,
from douban_movie.MovieItem import DoubanMovieItem 这个是从自己编写的MovieItem文件中导入的相应类 DoubanMovieItem
读者需要自行修改
items.py文件的代码:(Ps 我的文件名是MovieItem.py)
import scrapy
class DoubanMovieItem(scrapy.Item):
# define the fields for your item here like:
Rank= scrapy.Field() %电影排名
Name = scrapy.Field() %电影的名字
Author=scrapy.Field() %导演
Actor=scrapy.Field() % 主演
Score=scrapy.Field() %评分
Introduction = scrapy.Field() %介绍
Url=scrapy.Field() %电影的url链接
pipelines.py的代码如下:
import pymysql.cursors
import pymysql
from twisted.enterprise import adbapi
class DoubanMoviePipeline(object):
def __init__(self):
# 打开文件
# 连接数据库
self.conn = pymysql.connect(
host='localhost',
port=3306,
user='root',
passwd='123456',
db='wang',
)
self.cur = self.conn.cursor()
def process_item(self, item, spider):
sqli = "insert into douban_movie(id,title,author,actor,score,introducton,url) values(%s,%s,%s,%s,%s,%s,%s)"
# self.cur.execute(sqli,
# ('1', '2','3','4','5')) %只是为了验证Mysql和Pycharm是否链接成功
self.cur.execute(sqli, (item['Rank'],item['Name'], item['Author'],item['Actor'],item['Score'],item['Introduction'],item['Url']))
self.conn.commit()
return item
# 该方法在spider被开启时被调用。
def open_spider(self, spider):
pass
# 该方法在spider被关闭时被调用。
def close_spider(self, spider):
pass
这里使用的Mysql对数据进行存储
Setting.py 不需要写什么复杂的代码,只需要修改两个地方:
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0'
最后,scrapy框架的功能虽然很强大,但是不方便调试。一般运行的时候,都是在命令窗口,输入 scrapy crawl spider的名字
(Ps:这里是scrapy crawl douban)为了增加调试的方便性,我们可以编写一个main.py文件:
from scrapy.cmdline import execute
#调用execute可以执行scrapy脚本
import sys
import os
# sys.path.append('E:\PyProject\muke\muke')#但是换了工程之后,还得改路径
#所以
print(os.path.dirname(os.path.abspath('_file_')))
sys.path.append(os.path.dirname(os.path.abspath('_file_')))
execute(['scrapy','crawl','douban']) #相当于在命令窗口输入 scrapy crawl douban
有了main.py文件,则可以在pycharm中,直接运行main.py实现爬取功能,并且也能在其他py文件中设置断点调试。
最后爬取的数据表(这个是存储在Mysql数据库中的)为:
但是有个问题就是,在mysql中存的时候,Id代表的是电影的排名,很明显电影并没有按照排名依次存储,可以看到是乱序的。然后在pycharm中爬取的时候却是按照排名依次爬,如下面的图。这个问题困扰我好几天了,希望有知道的爬友可以解答下。