作业①
1.1题目
要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;
使用Scrapy+Xpath+MySQL数据库存储技术路线爬取当当网站图书数据
1.2实现过程
1.2.1 观察html源代码
可以看到每一本书的全部信息存放在一个li标签
中
接着查看li标签
内图书对应信息
1.2.2 代码实现
1、修改settings.py
- 修改打印日志等级
# 修改打印日志等级 关掉一些你看了也看不懂的东西
LOG_LEVEL = 'ERROR'
- 关闭遵循robots协议
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
- 设置请求头
DEFAULT_REQUEST_HEADERS = {
"user-agent" : "Mozilla/5.0 ......"
}
- 打开ITEM_PIPELINES
ITEM_PIPELINES = {
'dangdang.pipelines.DangdangPipeline': 300,
}
2、编写item.py
- 保存我们需要爬取的信息,添加需要爬取的信息
class DangdangItem(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
author = scrapy.Field()
publisher = scrapy.Field()
date = scrapy.Field()
price = scrapy.Field()
detail = scrapy.Field()
datalist = scrapy.Field()
3、编写pipelines.py
- 用于保存图书信息到数据库以及输出信息
4、编写PictureSpider
- 根据html源代码使用Xpath解析页面,得到如下表达式
lis = selector.xpath("//li['@ddt-pit'][starts-with(@class,'line')]")
for li in lis:
title = li.xpath("./a[position()=1]/@title").extract_first()
price = li.xpath("./p[@class='price']/span[@class='search_now_price']/text()").extract_first()
author = li.xpath("./p[@class='search_book_author']/span[position()=1]/a/@title").extract_first()
date = li.xpath("./p[@class='search_book_author']/span[position()=last()-1]/text()").extract_first()
publisher = li.xpath("./p[@class='search_book_author']/span[position()=last()]/a/@title").extract_first()
detail = li.xpath("./p[@class='detail']/text()").extract_first()
- 回调请求翻页
# 最后一页时link为None
link = selector.xpath("//div[@class='paging']/ul[@name='Fy']/li[@class='next']/a/@href").extract_first()
if link:
url = response.urljoin(link)
yield scrapy.Request(url=url, callback=self.parse)
1.3输出结果
MySQL数据库存储和输出格式如下:
作业②
2.1题目
要求:熟练掌握 scrapy 中 Item、Pipeline 数据的序列化输出方法;
使用scrapy框架+Xpath+MySQL数据库存储技术路线爬取外汇网站招商银行网数据。
2.2实现过程
2.2.1 观察html源代码
-
可以看到每个货币全部信息都存放在一个
tr标签
中 -
接着观察每个
tr标签
的内部内容,得到对应的信息
2.2.2 代码实现
1、修改settings.py
- 内容同作业①
2、编写item.py
- 保存我们需要爬取的信息,添加需要爬取的信息
class BankItem(scrapy.Item):
Currency = scrapy.Field() # 货币
TSP = scrapy.Field() # 现汇卖出价
CSP = scrapy.Field() # 现钞卖出价
TBP = scrapy.Field() # 现汇买入价
CBP = scrapy.Field() # 现钞买入价
Time = scrapy.Field()
datalist = scrapy.Field()
3、编写pipelines.py
- 用于保存外汇网站信息到数据库以及输出信息
class BankPipeline:
def process_item(self, item, spider):
try:
tply = "{0:^4}\t{1:^8}\t{2:<10}\t{3:<10}\t{4:<10}\t{5:<10}\t{6:<20}"
print(tply.format("序号".ljust(4, half2full(' ')), # 调整输出格式
"Currency".ljust(12, half2full(' ')),
"TSP".ljust(12, half2full(' ')),
"CSP".ljust(12, half2full(' ')),
"TBP".ljust(12, half2full(' ')),
"CBP".ljust(13, half2full(' ')),
"Time".ljust(20, half2full(' '))))
count = 1
for data in item['datalist']:
print(tply.format(str(count).ljust(4, half2full(' ')),
str(data[0]).ljust(8, half2full(' ')),
half2full(str(data[1])).ljust(10, half2full(' ')),
half2full(str(data[2])).ljust(10, half2full(' ')),
half2full(str(data[3])).ljust(10, half2full(' ')),
half2full(str(data[4])).ljust(10, half2full(' ')),
str(data[5]).ljust(20, half2full(' '))))
count += 1
dbpath = "D:/网络爬虫/test.db"
saveData2DB(item['datalist'], dbpath) # 保存到数据库
except Exception as err:
print(err)
return item
4、编写PictureSpider
- 使用Xpath解析页面数据,得到如下表达式
trs = selector.xpath('//*[@id="realRateInfo"]/table/tr')
for tr in trs[1:]: # 跳过第一行,因为第一行是标题
Currency = tr.xpath("./td[1]/text()").extract_first()
TSP = tr.xpath("./td[4]/text()").extract_first()
CSP = tr.xpath("./td[5]/text()").extract_first()
TBP = tr.xpath("./td[6]/text()").extract_first()
CBP = tr.xpath("./td[7]/text()").extract_first()
Time = tr.xpath("./td[8]/text()").extract_first()
2.3输出结果
MYSQL数据库存储和输出格式:
作业③
3.1题目
要求:熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容;
使用Selenium框架+ MySQL数据库存储技术路线爬取东方财富网“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。
3.2实现过程
3.2.1 观察html源代码
-
可以看到每个股票都存放在一个
tr标签
中 -
观察每个
tr标签
可以得到每条股票的详细信息 -
由于要求“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据
-
寻找“沪深A股”、“上证A股”、“深证A股”3个板块并进行点击跳转
3.2.2 代码实现
1、声明配置好的浏览器对象
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
driver= webdriver.Chrome(chrome_options=chrome_options)
# 等待反应
wait = WebDriverWait(driver, 5)
url = 'http://quote.eastmoney.com/center/gridlist.html#hs_a_board'
driver.get(url)
2、找到板块,点击跳转(以“沪深A股”为例)
# 沪深A股
board1 = wait.until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="nav_hs_a_board"]/a'))
)
board = driver.find_elements_by_xpath('//*[@id="nav_hs_a_board"]/a')[0].text
board1.click()
print('正在爬取', board)
get_products() # 解析页面得到需要的内容
3、观察html源代码后使用Xpath解析页面
def get_products():
time.sleep(3) #不加可能会报错,因为还未来得及翻页就开始解析页面
datalist = []
items = driver.find_elements_by_xpath('//*[@id="table_wrapper-table"]/tbody/tr')
try:
for item in items:
id = item.find_elements_by_xpath('./td[2]/a')[0].text # 股票代码
name = item.find_elements_by_xpath('./td[3]/a')[0].text # 股票名称
price = item.find_elements_by_xpath('./td[5]')[0].text # 最新价
change = item.find_elements_by_xpath('./td[6]/span')[0].text # 涨跌额
changeRate = item.find_elements_by_xpath('./td[7]/span')[0].text # 涨跌幅
vol_num = item.find_elements_by_xpath('./td[8]')[0].text # 成交量
vol = item.find_elements_by_xpath('./td[9]')[0].text # 成交额
datalist.append([id,name,price,change,changeRate,vol_num,vol])
except Exception as err:
print(err)
- 未加time.sleep之前执行代码会报错
Message: stale element reference: element is not attached to the page document
- 查找了原因,大概意思是说已经点击了翻页,但是还没有完成翻页,就开始解析页面,于是又爬了一次当前页,然后再要执行翻页时页面已经刷新了,前面找到的翻页元素已经过期了,导致无法执行
- 加入time.sleep之后解决此问题
3.3输出结果
MySQL数据库存储和输出格式如下:
心得体会
- 通过本次实验巩固了Scrapy框架的使用,更加熟悉翻页操作以及将数据保存到SQL的操作
- 巩固了Selenium爬取网页的方法,了解如何通过模拟浏览器行为进行翻页、切换页面操作