python爬虫从入门到放弃(一)——试用bs4, request爬百度股票

文章实践主要来自于:https://mp.weixin.qq.com/s/FiKqb06nz0K0AD9VUWJapw

 

爬虫流程:

明确目的(哪些数据),确认网页可爬,查看源网页是否有需要的数据。

 

 

bs4简介

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。

 

python

with方法--

with语句执行的解析:

  with context_expr() as var:

    doSomething()

  1. 当with语句执行时,便执行上下文表达式(context_expr)(一般为某个方法)来获得一个上下文管理器对象,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节:
  2. 一旦获得了上下文对象,就会调用它的__enter__()方法,将完成with语句块执行前的所有准备工作,如果with语句后面跟了as语句,则用__enter__()方法的返回值来赋值;
  3. 当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,__exit__()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。
  4. 因为上下文管理器主要作用于共享资源,__enter__()和__exit__()方法基本是完成的是分配和释放资源的低层次工作,比如:数据库连接、锁分配、信号量加/减、状态管理、文件打开/关闭、异常处理等。

  3、自定义类使用with来管理

 

完整代码示例:

 1 # -*- coding: utf-8 -*-
 2 
 3 
 4 # Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构,每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSoup , Comment .
 5 
 6 import requests
 7 from bs4 import BeautifulSoup
 8 import traceback
 9 import re
10 
11 
12 
13 def getHTMLText(url):
14     try:
15         r = requests.get(url)
16         r.raise_for_status()
17         r.encoding = r.apparent_encoding
18         return r.text
19     except:
20         return ""
21 
22 
23 def getStockList(lst, stockURL):
24     html = getHTMLText(stockURL)
25     # 返回的是BeautifulSoup对象
26     soup = BeautifulSoup(html, 'html.parser')
27     a = soup.find_all('a')
28     for i in a:
29         try:
30             href = i.attrs['href']
31             lst.append(re.findall(r"[s][hz]\d{6}", href)[0])
32         except:
33             continue
34 
35 def getStockInfo(lst, stockURL, fpath):
36     count = 0
37     for stock in lst:
38         url = stockURL + stock + ".html"
39         html_doc = getHTMLText(url)
40         try:
41             if html_doc == "":
42                 continue
43             infoDict = {}
44 
45             soup = BeautifulSoup(html_doc, 'html.parser')
46             # 寻找所有属性为stock-bets的div标签,构成一个list
47             stockInfo = soup.find('div', attrs={'class': 'stock-bets'})
48             # 找到所有class==bets-name的标签
49 
50             # 使用find方法返回的同样是bs4对象,find返回的是由bs4对象构成的list
51             name = stockInfo.find(attrs={'class': 'bets-name'})
52             # .text方法以list对象的方式返回tag的内容
53             infoDict.update({'股票名称': name.text.split[0]})
54             # 每个股票中每个key正好对应一个值,这里恰好不用数据处理
55             keyList = stockInfo.find_all('dt')
56             valueList = stockInfo.find_all('dd')
57             for i in range(len(keyList)):
58                 key = keyList[i].text
59                 val = valueList[i].text
60                 infoDict[key] = val
61                 # 内置open()函数,打开一个文件用于追加。
62                 # 如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
63             # 使用with语句时,如文件打开发生异常,可记录跟踪调查
64             with open(fpath, 'a', encoding='utf-8') as f:
65                 f.write(str(infoDict) + '\n')
66                 count = count + 1
67                 # 通过\r使得每次打印的时候光标换行到上一行开头,使得看起来进度条是连续的
68                 print("\r当前进度: {:.2f}%".format(count * 100 / len(lst)), end="")
69         except:
70             count = count + 1
71             print("\r当前进度: {:.2f}%".format(count * 100 / len(lst)), end="")
72             continue
73 
74 
75 def main():
76     stock_list_url = 'http://quote.eastmoney.com/stocklist.html'
77     stock_info_url = 'https://gupiao.baidu.com/stock/'
78     output_file = '/home/icarus/code/pachong_stock/BaiduStockInfo.txt'
79     slist = []
80     getStockList(slist, stock_list_url)
81     getStockInfo(slist, stock_info_url, output_file)
82 main()
View Code

 

posted @ 2018-03-11 17:04  IcarusYu  阅读(330)  评论(0编辑  收藏  举报