先放一张Scrapy的架构图:(开篇一张图,后面全靠编)
准备工作:安装了python3.7 pycharm编辑环境、Mysql数据库及scrapy相关库,熟悉xpath的用法,掌握Mysql数据库相关知识。
- 创建scrapy项目和spider类
打开cmd,敲scrapy startproject world500
最后面world500是项目的名称,可随意替换。接着cd world500
进去刚刚创建的文件夹里面,敲scrapy genspider demo fortunechina.com
后面的域名是用来限制爬取的网页,以防止抓取到别的页面。 - 分析财富网数据组成点击这里
可以发现榜单数据都在id="table1"的table下,每一个tr对应一行数据,不同的td则对应相应的数据。再往下翻,发现每一页只显示了50条数据:
但是我们右击鼠标点击查看源代码,发现这500条数据就在源代码里面,根本不需要翻页操作,只是前端的工程师利用js技术实现了分页。
- 利用Xpath解析数据
解析数据获得每一家公司的排名、名称、收入、利润、所在国家。
首先获得每一行的tr,然后在逐步从中获取详细数据。
利用Chrome Xpath helper检查xpath是否正确,发现一共得到了50条结果,我们的一页就只用50家公司,说明写对了>< 。
在创建的demo.py文件里的parse函数中,加入以下代码:
items = response.xpath('//table[@id="table1"]/tbody/tr')
for item in items:
rank = int(item.xpath('./td//text()')[0].extract())
name = item.xpath('./td//text()')[2].extract().strip()
income = item.xpath('./td//text()')[3].extract()
profit = item.xpath('./td//text()')[4].extract()
country = item.xpath('./td//text()')[5].extract()
- 在items.py 里面生成Item对象,并且完善parse函数
import scrapy
class World500Item(scrapy.Item):
rank = scrapy.Field()
name = scrapy.Field()
income = scrapy.Field()
profit = scrapy.Field()
country = scrapy.Field()
pass
然后在demo.py文件parse函数中加上:yield World500Item(rank=rank, name=name, income=income, profit=profit, country=country)
,这样,就可以将获取的数据交给别的部分处理,以便存入数据库。
- 写pipeline函数来存储数据
这里先连接数据库,import pymysql 通过第三方库来执行mysql语句,初始化的时候先创建表格,如果之前有表格了,那么就删掉重新创建,然后每取得一条信息就插入数据库,open_spider与数据库取得连接,close_spider断开与数据库的连接。注意:rank是mysql的保留字需要加上引号 ` ,esc键下面的那个符号。
import pymysql
class World500Pipeline(object):
def __init__(self):
self.db = pymysql.connect(host='localhost', port=3306, user='root', password='raymond', database='spiders',
charset='utf8')
self.cursor = self.db.cursor()
self.cursor.execute('DROP TABLE IF EXISTS world500')
self.cursor.execute(
'CREATE TABLE world500(`rank` int PRIMARY KEY ,name VARCHAR(80),`income(million dollar)` VARCHAR(20),`profit(million dollar)` VARCHAR(20),country VARCHAR(20))')
def process_item(self, item, spider):
sql = 'INSERT INTO world500 VALUES(%s,%s,%s,%s,%s)'
try:
self.cursor.execute(sql, (item['rank'], item['name'], item['income'], item['profit'], item['country']))
self.db.commit()
print('{}下载完成'.format(item['name']))
except:
print('{}下载失败'.format(item['name']))
self.db.rollback()
return item
def close_spider(self):
self.cursor.close()
self.db.close()
6.修改settings.py文件
-
修改
ROBOTSTXT_OBEY = False
,这样就可以爬取那些robots协议禁止的地方的数据。 -
修改headers,来达到反爬的目的
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36',
'Referer': 'https://www.baidu.com/s?ie=UTF-8&wd=%E4%B8%96%E7%95%8C%E4%BA%94%E7%99%BE%E5%BC%BA',
'Host': 'www.fortunechina.com'
}
- 修改pipeline,这样程序就会执行pipeline函数来存储数据,300代表运行的优先级,我们这里只有一个函数,不需要修改。
ITEM_PIPELINES = {
'world500.pipelines.World500Pipeline': 300,
}
- 运行爬虫
打开cmd,敲scrapy crawl demo
,这样我们的爬虫程序就完成了。
运行结果: