Python爬虫代码基本框架
框架如下:
1 2 3 4 5 6 7 8
| def getHTMLtext(url): try: r = requests.get(url, timeout=30) r.raise_for_status() 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&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,可能还有许多待优化的地方。
完(๑′ᴗ‵๑)