手写爬虫实战

图片爬虫

学习了爬取网页技巧和正则表达式之后, 通过图片爬取来进行一次实战练习.

情景: 京东商城手机图片爬取

我的手机依然是高二购买的IPhone5S, 手机到现在已经整整用了3年了. 每当我看到新的手机时, 总是眼馋的不行, 奈何口袋里没有足够的银两, 只能时不时逛一逛商城解除以下眼馋~ 所以, 今天的任务就是爬取京东商城所有的手机图片.

第一步, 获得URL

第二步, 观察页面源码, 找到图片的描述.

  • 鼠标再页面中点击右键, 单机查看源码

右键

  • 可以看到html源码后, 查找图片的描述, 这里的技巧是:

    • 观察原网页, 找到任意图片下面的描述, 如 小米 Note3 ….xxx

    • 再源码页面 Ctrl+f 查找这些文字, 观察文字附近的标签, 找到:

    • <img width="220" height="220" class="err-product" data-img="1" src="//img10.360buyimg.com/n7/jfs/t12859/355/1502498371/155178/f5e7e927/5a213b0aNcbdbb90a.jpg" />
    • 这个就是图片标签

第三步, 根据图片的描述, 设计图片的正则表达式

参考正则表达式 , 可以得到图片的正则表达式为

pat = '<img width="220" height="220" class="err-product" data-img="1" (.*?) />'

当然, 这还不是图片资源网址应该有的格式, 我们需要的只是 src后面的部分 , 所以需要再pat匹配之后的结果, 继续匹配

pat2 = '//img.+?\.jpg'

第四步, 根据正则表达式获得图片资源的链接, 爬取并保存图片

import re
import urllib.request

def craw(url,page):
html = urllib.request.urlopen(url).read()
html = str(html)
pat = '<img width="220" height="220" class="err-product" data-img="1" (.*?) />'
result = re.compile(pat).findall(html)
pat2 = '//img.+?\.jpg'
imglist = list()
for each in result:
temp = re.compile(pat2).findall(each)
imglist.append(temp[0])
x=1
for each in imglist:
imgname = "/mnt/c/Users/Hox/Documents/Temp/img/"+str(page)+str(x)+".jpg"
imgurl = "http:"+ each
print(imgurl)
try:
urllib.request.urlretrieve(imgurl,filename=imgname)
pass
except urllib.error.URLError as e:
print(e)
if hasattr(e,"code"):
x+=1
pass
if hasattr(e,"reason"):
x+=1
pass
finally:
x+=1
pass

for i in range(1,10):
url = "http://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page="+str(i)+"&s=59&click=0'"
craw(url,i)

效果图

效果图

爬取一个网页上所有的URL

套路基本和之前一样, 这个相对简单, 直接上代码.

import urllib.request
import re

def GetLink(url):
req = urllib.request.Request(url)
req.add_header('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36')
html = urllib.request.urlopen(req).read()
html = str(html)
pat = '(?:https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
urls = re.compile(pat).findall(html)
urls = list(set(urls))
for each in urls:
print(each)

url = str(input("url:"))
if url.find('http')==-1:
url = 'http://'+url
pass
GetLink(url)

结果:

hox@ColdCode:~/work-place/pystudy/crawTest$ python3 code.py
url:www.csdn.net
http://blog.csdn.net/carson_ho/article/details/79314325#comment_form
http://blog.csdn.net/X8i0Bev/article/details/79071576
http://blog.csdn.net/u013088062/article/details/50893901
http://blog.csdn.net/zuochao_2013/article/details/56024172
http://blog.csdn.net/blockchain_lemon/article/details/79395162
http://blog.csdn.net/b644ROfP20z37485O35M/article/details/79055019
http://gitbook.cn/gitchat/geekbook/5a582543e286423809d4a7e5?utm_source=sy18022402
http://blog.csdn.net/tMb8Z9Vdm66wH68VX1
http://blog.csdn.net/a2Ni5KFDaIO1E6/article/details/79070518
http://blog.csdn.net/dqcfkyqdxym3f8rb0/article/details/79402975
http://blog.csdn.net/b644ROfP20z37485O35M/article/details/79055019#comment_form
http://blog.csdn.net/hanli1992/article/details/79380262
http://qualcomm.csdn.net/
http://blog.csdn.net/csdnnews/article/details/79395044
http://blog.csdn.net/FYGu18/article/details/79063230#comment_form
http://blog.csdn.net/FYGu18/article/details/79063230
http://huawei.csdn.net/
http://blog.csdn.net/MOY37RQW1JarN33BgZk/article/details/79051044#comment_form
http://blog.csdn.net/meyh0x5vDTk48P2/article/details/79072666
http://blog.csdn.net/kXYOnA63Ag9zqtXx0
http://blog.csdn.net/g6U8W7p06dCO99fQ3/article/details/79064119
http://blog.csdn.net/age12v/article/details/79071815#comment_form

….

爬取糗事百科上的所有段子

如果上面两个例子略显无趣, 下面这个例子可算是相当又用了. 省去一页一页的手动翻页, 将所有段子爬取下来. 貌似很有趣的样子.

  • 段子再html中 的位置如下
<div class="content">
<span>


表姐今年36,意外怀孕,表姐夫有些担心,就特别关心。中午在表姐吃饭,有碗汤比较重,就让外甥去端,汤不小心洒了点出来。表姐夫马上去看表姐有没>有烫到,然后才看到外甥的羽绒服被汤弄脏了,就说:“记得自己洗衣服,你妈妈不能碰冷水”。外甥有些不满:“家里水果也是我切的,妈妈什么都不用做。
”表姐夫回到:“你要是怀孕了,我也把你当祖宗供着。”……刚刚用表姐家的电脑,一看搜索记录都是:13岁的男孩如何怀孕,快速怀孕的方法…简直可怕^A[中
毒了]

</span>

</div>

代码如下

import re
import requests

def craw(url):
header = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36'}
req = requests.get(url,headers=header)
html = req.text
pat = re.compile('<div class="content">\n<span>\n(.+?)\n</span>',re.S) ### 这个re.S至关重要, 表示匹配换行符, 而默认不匹配
paras = re.findall(pat,html)
fhandle = open('/mnt/c/Users/Hox/Desktop/save.txt','a')
for each in paras:
each = re.sub('<br/>',' ',each)
fhandle.write(each+'\n')
pass
fhandle.close()

for i in range(1,12):
url = 'https://www.qiushibaike.com/8hr/page/' + str(i)
craw(url)

结果

段子