mooc爬虫课程第三周学习笔记之二(实例分析)

淘宝爬虫实例分析

功能描述

目标:获取淘宝搜索页面的信息,提取其中的商品名称和价格

解决的问题:

淘宝的搜索接口
翻页的处理

使用requests与re库

在淘宝中搜索书包后
起始页
https://s.taobao.com/search?q=书包&js=1&stats_click=search_radio_all%
3A1&initiative_id=staobaoz_20170105&ie=utf8
“书包”
第二页
https://s.taobao.com/search?q=书包&js=1&stats_click=search_radio_all%
3A1&initiative_id=staobaoz_20170105&ie=utf8&bcoffset=0&ntoffset=0&p4pp
ushleft=1%2C48&s=44
第三页
https://s.taobao.com/search?q=书包&js=1&stats_click=search_radio_all%
3A1&initiative_id=staobaoz_20170105&ie=utf8&bcoffset=‐3&ntoffset=‐
3&p4ppushleft=1%2C48&s=88
可看出每页展示44个商品。以此特征进行翻页处理

main函数

def main():
	goods = '书包'
	depth = 3
	start_url = 'https://s.taobao.com/search?q=' + goods
	infoList = []
	for i in range(depth):
		try:
			url = start_url + '&s=' + str(44*i)
			html = getHTMLText(url)
			parsePage(infoList, html)
		except:
			continue
	printGoodsList(infoList)

getHTMLText函数

def getHTMLText(url):
	try:
		r = requests.get(url, timeout=30)
		r.raise_for_status()
		r.encoding = r.apparent_encoding
		return r.text
	except:
		return ""

parsePage函数

def parsePage(ilt, html):
	try:
		plt = re.findall(r'\"view_price\"\:\"[\d\.]*\"',html)
		tlt = re.findall(r'\"raw_title\"\:\".*?\"',html)
		for i in range(len(plt)):
			price = eval(plt[i].split(':')[1])
			title = eval(tlt[i].split(':')[1])
			ilt.append([price , title])
	except:
		print("")

printGoodsList函数

def printGoodsList(ilt):
tplt = "{:4}\t{:8}\t{:16}"
print(tplt.format("序号", "价格", "商品名称"))
count = 0
for g in ilt:
count = count + 1
print(tplt.format(count, g[0], g[1]))

但淘宝已经禁用爬虫,故爬取无结果
但代码值得学习。

爬取股票有关信息

使用模块

requests-bs4-re库

候选网站

新浪股票:

http://finance.sina.com.cn/stock/

百度股票:

https://gupiao.baidu.com/stock/
选取原则: 股票信息静态存在于HTML页面中,非js代码生成
没有Robots协议限制
选取方法: 浏览器F12,源代码查看等
选取心态: 不要纠结于某个网站,多找信息源尝试
通过网站代码发现新浪的数据是动态的不适合爬取,顾轩泽百度股票

数据网站的确定

获取股票列表:
东方财富网:http://quote.eastmoney.com/stocklist.html
获取个股信息:
百度股票:https://gupiao.baidu.com/stock/
单个股票:https://gupiao.baidu.com/stock/sz002439.html

程序结构设计

步骤1: 从东方财富网获取股票列表
步骤2: 根据股票列表逐个到百度股票获取个股信息
步骤3: 将结果存储到文件

实例编写

main()函数

输入url并且输入文件储存路径,调用相关函数

getHTMLText()函数

获得url中的html信息

getStockList()函数

获得东方财富网中想要的那串数字,用于指引到百度股票中的搜索

getStockInfo()函数

在百度股票中检索到相关信息并存储。

全代码

import requests
import re
from bs4 import BeautifulSoup
import traceback #用于错误检索
def getHTMLText(url):
	try:
		r=requests,get(url)
		r.raise_for_status()
		r.encoding=r.apparent_encoding
		return r.text
	except:
		return ""
def getStockList(lst,stockURL):
	html=getHTMLText(stockURL)
	soup=BeautifulSoup(html,'html.parser')
	a=soup.find_all('a')
	for i in a:
		try:
			href=i.attr['href']
			lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
		except:
			continue
def getStockInfo(lst,stockURL,fpath):
	for stock in lst:
		url=stockURL+stock+".html"
		html=getHTMLText(url)
		try:
			if html=="":
				continue
			infoDict={}
			soup=BeautifulSoup(html,'parser')
			stockInfo=soup.find('div',attrs={'class':'stock-bets'})
			name = stockInfo.find_all(attrs={'class':'bets-name'})[0]
            infoDict.update({'股票名称': name.text.split()[0]})
            
            keyList = stockInfo.find_all('dt')
            valueList = stockInfo.find_all('dd')
            for i in range(len(keyList)):
                key = keyList[i].text
                val = valueList[i].text
                infoDict[key] = val
            with open(fpath, 'a', encoding='utf-8') as f:
                f.write( str(infoDict) + '\n' )
        except:
            traceback.print_exc()
            continue

def main():
    stock_list_url = 'http://quote.eastmoney.com/stocklist.html'
    stock_info_url = 'https://gupiao.baidu.com/stock/'
    output_file = 'D://BaiduStockInfo.txt'
    slist=[]
    getStockList(slist, stock_list_url)
    getStockInfo(slist, stock_info_url, output_file)

main()

实验之后,得不出任何结果,考虑到有可能是网站的缘故,故在main函数中的url用以下代码替换之后

	stock_list_url = 'http://app.finance.ifeng.com/list/stock.php?t=ha'
    stock_info_url = 'https://www.laohu8.com/stock/'

得出有效结果

代码优化

1.节省时间

由于已经知道获取有效数字的网站的编码是utf-8,所以直接赋值,节省了对于r.apparent_encoding的计算时间
同理对于股票具体网站的编码是’GB2312’,故直接使用,而不用让系统去计算最有可能编码方式

2.优化用户体验

通过添加动态更新的代码,让用户能够实时看到代码的进度。
全代码

import requests
from bs4 import BeautifulSoup
import re
import traceback
 
def getHTMLText(url, code='utf-8'):
   try:
       r = requests.get(url)
       r.raise_for_status()
       r.encoding = code
       return r.text
   except:
       print('爬取失败')
 
def getStockList(lst, stockURL):
    html = getHTMLText(stockURL, 'GB2312')
    soup = BeautifulSoup(html, 'html.parser')
    a = soup.find_all('a')
    for i in a:
        try:
            href = i.attrs['href']
            lst.append(re.findall(r"[s][hz]\d{6}", href)[0]) ## 匹配 a 标签中 href 属性以 s 开头,中间是 h 或 z ,最后是6位数字
        except:
            continue
 
def getStockInfo(lst, stockURL, fpath):
    ## 去掉列表里的重复选项--将列表转换为集合再转换为列表
    lst = list(set(lst))
    count = 0
    for stock in lst:
        url = stockURL + stock[-6:]
        html = getHTMLText(url)
        try:
            if html == '': ## 判断是否空页面
                continue
            infoDict = {} ## 定义一个字典,存储股票信息
            soup = BeautifulSoup(html, 'html.parser')
            stockInfo = soup.find('div', attrs={'class':'stock-info'})
 
            name = stockInfo.find_all(attrs={'class':'name'})[0]
            price = stockInfo.find_all(attrs={'class': 'latest'})[0]
            infoDict.update({'股票名称':name.text.split()[0], '最新行情':price.text.split()[0]})
 
 
            keyList = stockInfo.find_all('dt')
            valueList = stockInfo.find_all('dd')
 
            for i in range(len(keyList)):
                key = keyList[i].text
                val = valueList[i].text
                infoDict[key] = val
 
 
            ## 将字典写入文件中
            with open(fpath, 'a', encoding='utf-8') as f:
                f.write(str(infoDict) + '\n')
                count = count + 1
                ## 增加动态进度显示
                print('\r当前进度:{:.2f}%'.format(count*100/len(lst)), end='')
 
        except:
            traceback.print_exc()  ## 获得发生异常的错误信息
            continue
 
def main():
    stock_list_url = 'http://app.finance.ifeng.com/list/stock.php?t=ha'
    stock_info_url = 'https://www.laohu8.com/stock/'
    output_file = 'D:\\StockInfo.txt'
    slist = []
    getStockList(slist, stock_list_url)
    getStockInfo(slist, stock_info_url, output_file)
 
main()

需使用cmd命令行窗口运行,或者在vs中,因为 \r 在IDLE中无法刷新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值