Python爬虫入门(一)

版权声明:文章禁止转载 https://blog.csdn.net/weixin_43477010/article/details/85333510

1.适配环境

note:部分神舟笔记本bios默认开启virtualization technology,可以用任务管理器确认
在这里插入图片描述
virtualbox
ubuntu18
vim
python3.6

1.1.ubuntu入门

sudo 给权限
ls 返回当前目录下的所有文件的名称,返回详细信息用ll
apt-get install/remove xxx 下载或删除xxx
mkdir 创建文件夹
pwd 返回当前目录
mv move文件到另一个文件中 mv spder.py test/
find find . -name spider.py查找名为 spider.py的文件,find ./test/ -name spider.py就是只对test目录下查找

rm
rm -f 强制删除文件
rm -rf 删除文件夹

对爬虫有帮助
ps查看进程
ps a 看到所有进程
ps aux | grep vscode 查看vscode的进程,可以用返回的编号,使用kill 编号,删除。

grep -r re ./test在test文档中搜索文件中有re字样的,返回./test/spider.py import re

git clone xxxx.git 复制代码到本地
git pull对代码进行更新

1.2 vim入门

在非编辑界面输入:,进入命令模式,:wq表示写入并退出,:q!强制退出,:set number显示行数。
:数字光标跳到指定数字行,:gg跳到第一行, :GG跳到最后一行

h左,j下,k上,l右

在非编辑界面下,按a进入编辑模式,按i进入insert的编辑模式,o表示进入并自动加一个换行。

非编辑模式下按dd,删除光标所在行,按u撤回指令,按x删除一个字节。

文本内复制 1,10 co 16 把1到10行复制到16。用m代替co就是剪切过去
按住shift+insert将剪切板的东西复制到vim中

2.HTML

在这里插入图片描述
在这里插入图片描述
<html>是开头,</html>是结束,其中的其他开闭和标签为其的子集
试验一下,可用火狐打开
在这里插入图片描述
在这里插入图片描述

<a href=“http://www.baidu.com”>百度</a> 超链接
<title>xx</title> 网页标题
<h1>xx</h1> 标题1
<p> xx</p> 段落内容
<img src=“www.xxx.com/x.jpg”/> 图片

<!DOCTYPE html>表示文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档。

2.1链接标签

页内跳转和javascrpt的响应
在这里插入图片描述

2.2 table标签

方便记忆
tr-table row
th-table head
td-table data
在这里插入图片描述

其中boder表示表格边框,caption是大标题

<table>
	<captioon> 表格标题</captioon> 
	<tr> #按行输入,第一行为table head
		<th> head1 </th>
		<th> head2 </th>
	</tr> # 由table head组成的第一行键入完毕
	
	<tr> #按行输入,键入的为td,即单元格内容
		<td> data1</td>
		<td> data1</td>
	</tr> # 由td组成的第二行键入完毕
......
</table>

在这里插入图片描述

2.3 DOM属性

给标题h1中加入一个a标签,带name属性,值为turnmoil,则可用超链跳至此处
在这里插入图片描述

在这里插入图片描述
常见的属性由这几种。
在这里插入图片描述

由一个class可以找到一组elements,而id只对应一个element
在这里插入图片描述

查询是否有同样的标签出现在网页,右键检查,点进console,键入document.get(用tab补全)

这是按照class的名字来检索的,当然也可以使用tag的名字,用的是document.getElementsByTagName
在这里插入图片描述
在这里插入图片描述

更进一步的查找
在这里插入图片描述在这里插入图片描述

2.4 CSS

style属性
在这里插入图片描述

加上style属性,直接更改外观样式。
在这里插入图片描述

若要全部都修改,可以用外嵌的方法,先给需要修改的地方加一个class名,再以此建一个css文件,放在在开头,则所有相关的地方都被修改了。此处.main-content就是选择所有class="main-content"的元素的意思。关于更多css选择器,可以看CSS选择器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.第一个爬虫

3.1 requests包初探

在这里插入图片描述
试试爬一下本篇文章~
在这里插入图片描述
在这里插入图片描述
成功了,在一堆字符中找到本篇文章
在这里插入图片描述

requests.get返回一个类,里面一个属性就是status_code,返回为200,表示爬取成功。
在这里插入图片描述
若返回的是json格式的,用resp.json()即可(resp是requests.get赋值的变量),就转为了字典格式。

成功调用 .json() 并不完全意味着响应的成功。有的服务器会在失败的响应中包含一个 JSON 对象(比如 HTTP 500 的错误细节)。这种 JSON 会被解码返回。要检查请求是否成功,请检查.status_code的值是否和你的期望相同。

resp.encoding是编码,本文返回的是UTF-8
在这里插入图片描述
看来是正确的。

让爬虫更像人类,需要设置headers,
在这里插入图片描述
若直接复制会出现报错,UnicodeEncodeError: 'latin-1' codec can't encode character '\u2026' in position 30,则是因为直接对header进行复制,应该要点开再复制,因为user-agent太长,中间可能会省略了
在这里插入图片描述

注意是要的request header,而不是response header,而且诸如Postman-token, If-Modified-Since 的内容要去掉,本次把cookie也拿掉了。此外,用resp.headers可以返回请求头

3.2 字符编码和文件读写

但是如果encoding发生错误,会导致乱码。这里的新浪文本应该是utf-8,但是requests包把它当成了iso8859-1的编码(多为西欧语系在用,字符少,而中文字符多,不适合),这里open中的"w+",可参见link
在这里插入图片描述
若后面不加b,则说明以字符串方式(unicode)打开
在这里插入图片描述
比如这里,需要用ab来打开。比如网上下载图片保存,就要用b,因为是二进制的不是字符串。

在这里插入图片描述
在这里插入图片描述

编码不同,读出来的内容也就不同。
在这里插入图片描述

一些编码相关的知识:
在这里插入图片描述
UTF-8可以1到7个字节
在这里插入图片描述
py2.7转unicode可以直接u"你好"
在这里插入图片描述

str—>(encode)—>bytes,bytes—>(decode)—>str,decode的作用是将其他编码的字符串转换成unicode编码,encode的作用是将unicode编码转换成其他编码的字符串。

在linux系统下,执行如下代码 len(“你好python”) 输出结果正确的是:
Python2.7下中文字符串默认是utf-8编码。
utf-8编码的一个中文占3个字节,2个中文是6个字节,加6个英文字母,输出结果是12
Python3.6下字符串默认是Unicode字符编码, 2个汉字字符加6个英文字符,输出结果是 8

我们加入encoding,得到的网页就是utf-8了。但是返回r.content就不行,因为是encoding不改变content只改变text,所以是字节流(python提示为bytes,而python中的str格式为unicode),要用wb读写。
在这里插入图片描述
在这里插入图片描述

3.3 爬取文件的命名

直接命名法
如果爬取整个网站,可能会出现同名的情况,所以命名是很重要的
比如新浪的网页,有一个时间2018-12-31的文档,所以doc-ihqfskcn2857665是不是唯一的,我们不知道。
http://sports.sina.com.cn/basketball/nba/2018-12-31/doc-ihqfskcn2857665.shtml

而马蜂窝网站的游记,是直接用一串数字代表,应该就是唯一的
https://www.mafengwo.cn/i/11505790.html
其中,http为协议(也可能为https,ftp和file),www.mafengwo.cn为域名,也叫domain;而basketball/nba/2018-12-31为路径,path;最后的doc-ihqfskcn2857665为网页的名字。我们可以用字符串的内置函数rfind来找(也就是从右边开始搜索,找到右边第一个/的下一个字符到结尾的index,直接冒号后面不加东西也是可以的)
在这里插入图片描述
得到:
在这里插入图片描述

获得domain:

start_pos = url.find("//")+2
end_pos = url.find("/", start_pos)
domain = url[start_pos: start_end]

filename = domain + "_" + filename # 这里的filename也就是之前的url[url.rfind("/")+1:]

可能会在尾部一个?,其后面跟着一个参数,可能是浏览器信息或跳转信息,如果留着可能造成爬取网页重复(ref, usr等参数,比如https://baike.baidu.com/item/百科/29?fr=aladdin,去掉?fr=aladdin对内容没影响),也可能是用来指明网页的参数(如https://www.youtube.com/watch?v=w3eOMmTjCOQ&index=8&list=PLUM8x224JrX-4MT-9Fp5omT_r5nazCurz),所以不一定都能删除,可以自己删除看看会不会对网页内容有影响。但大多数情况下对内容没影响,简单的处理方法就是直接删除url[url.find("?")]

MD5命名
也就是用连接的hash值直接对文件命名。每个文字的变化都会让md5发生明显变化。另外md5可能会重名,只是概率特别小。在ubuntu中,可以用md5sum 文件名,来查询文件的md5值
在这里插入图片描述
我们可以使用hashlib包来搞定,方法如下:
在这里插入图片描述
打印:
在这里插入图片描述
如果我们使用md5的方法,我们在url的信息就丢失了,比如一些分类信息和url的路径有关,这时我们用数据库储存这些信息。

我们也能用时间戳来命名,但是要用小的时间,比如毫秒。
百度的消歧义方法:同名的底下再加一个参数在后面
在这里插入图片描述

3.4 with语法

可以用函数with来省略close的步骤。

with open(filename, "w") as f:
	f.write(resp.text)

实质就是
在这里插入图片描述
上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
在这里插入图片描述
with a() as b, 用_enter_的返回值给a赋值,当with下的语句结束后,调用_exit_方法
在这里插入图片描述

给个例子
在这里插入图片描述
先执行__init__做初始化,
再根据with语法:
先执行__enter__
再执行do_something
最后无论有无异常出现都必须执行__exit__

猜你喜欢

转载自blog.csdn.net/weixin_43477010/article/details/85333510