先看看当当网的图片
查看一下页面源码找到我们要爬的图片数据格式和位置
图片数据存放的很容易取,用正则表达式来匹配:
r"<img data-original='(.*?)' src"
导入需要的包
import urllib.requestimport reimport osimport sysimport ssl
设置请求头
在请求网页爬取的时候,输出的text信息中会出现抱歉,无法访问等字眼,这就是禁止爬取,需要通过反爬机制去解决这个问题。
headers是解决requests请求反爬的方法之一,相当于我们进去这个网页的服务器本身,对反爬虫网页,可以设置一些headers信息,模拟成浏览器取访问网站 。
怎么查看请求头
首先在当前网页右键,查看页面源码。或者F12键「不同系统查看方式不太一样」。
然后在Network一栏找到Doc,如下对应的位置就是我们本机的请求头了。
注意:
headers中有很多内容,主要常用的就是user-agent 和 host,他们是以键对的形式展现出来,如果user-agent 以字典键对形式作为headers的内容,就可以反爬成功,就不需要其他键对;否则,需要加入headers下的更多键对形式。
对于爬虫来说,如果一直使用同一个ip同一个user-agent去爬一个网站的话,可能会被禁用,所以我们还可以用用户代理池,循环使用不同的user-agent.
方法:将各个浏览器的user-agent做成一个列表,然后每次爬取的时候,随机选择一个代理去访问.
添加请求头
headers = { "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" }
向服务器提交数据
Http常见请求方法:
GET:从指定的资源请求数据。
post:向指定的资源提交要被处理的数据。
requests对象的get和post方法都会返回一个Response对象,这个对象里面存的是服务器返回的所有信息,包括响应头,响应状态码等。
get方法
GET 请求可被缓存
GET 请求保留在浏览器历史记录中
GET 请求可被收藏为书签
GET 请求不应在处理敏感数据时使用
GET 请求有长度限制
GET 请求只应当用于取回数据
post方法
POST 请求不会被缓存
POST 请求不会保留在浏览器历史记录中
POST 不能被收藏为书签
POST 请求对数据长度没有要求
urllib.request
request主要负责构建和发起网络请求。
response = urllib.request.
urlopen
(url,data=None, [timeout, ]*)
返回的response是一个http.client.HTTPResponse object。
urllib.request.urlopen()默认是get请求,但是当data参数不为空时,则会发起post请求。
设置timeout参数
如果请求超出我们设置的timeout时间,会跑出timeout error 异常。
response = urllib.request.urlopen(url, data=param, timeout=10)。
以下是全部代码
import urllib.requestimport reimport osimport sysimport ssl
def dangdangCrawler(url, toPath): headers = { "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0", "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" } req = urllib.request.Request(url, headers=headers) # 使用ssl创建未验证的url context = ssl._create_unverified_context() response = urllib.request.urlopen(req, context=context, timeout=10)
htmlsStr = response.read().decode("gbk")
pat = r"<img data-original='(.*?)' src" re_img = re.compile(pat, re.S) imgsList = re_img.findall(htmlsStr) num = 1 for imgUrl in imgsList: imgPath = os.path.join(toPath, str(num)+".jpg") # print(imgUrl) # 图片下载保存到本地 urllib.request.urlretrieve(imgUrl, filename=imgPath) num += 1
url = r"http://baby.dangdang.com/20170911_cijj" toPath = r"/dangdang/crawlerProject/image" dangdangCrawler(url, toPath)
来看看效果
打开一张图看看。。。
我这里爬取的是图片,如果我们是解析网页内容,则需要注意;
服务器返回的网页部分会存在.content和.text两个对象中。
两者区别在于,content中间存的是字节码,而text中存的是Beautifulsoup根据猜测的编码方式将content内容编码成字符串。
直接输出content,会发现前面存在b'这样的标志,这是字节字符串的标志,而text是',没有前面的b,对于纯ascii码,这两个可以说一模一样,对于其他的文字,需要正确编码才能正常显示。
大部分情况建议使用.text,因为显示的是汉字,但有时会显示乱码,这时需要用.content.decode('utf-8'),中文常用utf-8和GBK,GB2312等。这样可以手工选择文字编码方式。.text是现成的字符串,.content还要编码,但是.text不是所有时候显示都正常,这是就需要用.content进行手动编码
简而言之:
text返回的是Unicode型的数据
content返回的是是二进制的数据。
也就是说,如果你想取文本,可以通过r.text。
如果想取图片,文件,则可以通过r.content