Python爬虫代码基本框架

框架如下:

1
2
3
4
5
6
7
8
def getHTMLtext(url):
try:
r = requests.get(url, timeout=30)
r.raise_for_status() #如果状态不是200,引发HTTPError异常
r.encoding = r.apparent_encoding
return r.text
except:
return "产生异常"

尝试爬取当当网商品搜索结果页面

刚刚学完爬虫的基本知识,也基本会用request、bs4和re这三个库了,于是尝试爬取当当网商品搜索页面,这是本人第一次爬虫。
这次的爬取目标是获取搜索页面的所有商品价格和名称,所以我们对爬下来的HTML文本做了些许分析。

搜索关键词假设是“六年级”,那么与第一个商品有关的HTML便如下(用了YAML代码块来表示,请见谅)。可以发现,与第一个商品有关的名称位于名称为p、属性为name的标签下,而价格则位于名称为p、属性为price的标签下。值得注意的是,这两个标签之间还隔着一个名称为p、属性为detail的标签,而且这三个标签一并构成了平行标签
为了解析html更方便,在找到名称为p、属性为name的标签之后,直接用next_sibling访问下一个平行标签。用正则表达式匹配商品价格和名称之后,存入键值对之中,并打印到txt文件里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<p class="name" name="title">
<a dd_name="单品标题" ddclick="act=normalResult_title&amp;pos=20916683_0_1_q" href="http://product.dangdang.com/20916683.html" name="itemlist-title" target="_blank" title=" 六年级英语阅读理解与完型填空加油站 ">
<font class="skcolor_ljg">
六年级
</font>
英语阅读理解与完型填空加油站
</a>
</p>
<p class="detail">
</p>
<p class="price">
<span class="search_now_price">
¥19.80
</span>
<a class="search_discount" style="text-decoration:none;">
定价:
</a>
<span class="search_pre_price">
¥22.00
</span>
<span class="search_discount">
(9折)
</span>
</p>

全代码如下(这里只能爬取搜索结果第一页):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import requests
import re
from bs4 import BeautifulSoup

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

def parseHTML(html):
dict = {}
pat_title = re.compile(r'title=\".*?\"')
pat_price = re.compile(r'¥\d*[.]\d{2}')
soup = BeautifulSoup(html, 'html.parser')
for tag in soup.find_all('p', 'name'):
try:
t = pat_title.search(str(tag)).group(0).split("\"")[1]
p = pat_price.search(str(tag.next_sibling.next_sibling)).group(0)
dict[t] = p
except:
continue
return dict

def main():
key = "C++"
url = "http://search.dangdang.com/?key=" + key
html = getHTMLtext(url)
dict = parseHTML(html)
path = "D:\\当当网爬取结果(" + key + ").txt"
tplt = "{:4}\t{:8}\t{:16}"
with open(path, "w", encoding="utf-8") as f:
count = 0
f.write(tplt.format("序号","价格","商品名称")+"\n")
for d in dict.items():
count += 1
f.write(tplt.format(count, d[1], d[0])+"\n")

main()

输出结果如下:

第一次做爬虫,而且也是刚刚上手python,可能还有许多待优化的地方。
完(๑′ᴗ‵๑)