爬虫 plus

3
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# 导入所需模块
import requests
from bs4 import BeautifulSoup
from os import _exit,path,remove,system
from time import ctime
# import json

cookie = 'this is cookies'
cookies = {i.split("=")[0]:i.split("=")[-1] for i in cookie.split("; ")}

headers = {'User-Agent':'this is User-Agent'
}

site_url=open('site.txt','r+',encoding='utf-8') # 可读可写

url_read=site_url.read()
url_dict=eval(url_read) # 转化为字典
# site=set(url_dict) # 这样会输出集合,不方便遍历
site=list(url_dict.keys()) # 需要从dict_key强转为list

def add_site():
print(url_dict)
url_dict[input('输入站点代号:')]=input('请输入站点url:')
print(url_dict)
site_url.seek(0)
site_url.write(str(url_dict))

while 1:
# system('cls')
print('-1.add new site')
print('0.quit')
for i in range(len(url_dict)):
print(str(i+1)+'.'+site[i])
num=int(input('请输入站点编号:'))
if num==0:
site_url.close()
_exit(0)
if num==-1:
add_site()
site_url.seek(0)
url_read=site_url.read()
site=list(url_dict.keys()) # 需要从dict_key强转为list
continue
page_num=int(input('请输入抓取页数:'))
file_path = 'data'+'_'+site[num-1]+'.txt'
if path.exists(file_path):
remove(file_path)

f=open(file_path, 'a', encoding='utf-8')
f.write('抓取时间:'+ctime()+'\n')
f.close()

for page in range(page_num):
f=open(file_path, 'a', encoding='utf-8')
f.write('\n\n第'+str(page+1)+'页:\n')
f.close()

url = url_dict[site[num-1]]+str(page+1)
print(url)
response = requests.get(url, headers=headers,cookies=cookies)
soup = BeautifulSoup(response.text, 'lxml')
for each in soup.find_all('tbody'):
title = each.find('a',class_ = 'topic').get_text(strip=True)
f=open(file_path, 'a', encoding='utf-8')
f.write('\n'.join([title]))
f.write('\n')
f.close()
print('response.status_code ==',response.status_code)
site_url.close()

改进

增加了通过文件读写来更新site即站点列表;

增加了交互式查询的功能;

增加了抓取时间和抓取页面的页数(如果是用于数据分析,那这个属于是多余,但如果爬出来的结果是给人看的,那就显得很有必要了。)

注意点

文件的打开方式

只介绍我用到的两种,和试图用的一种

‘r+’:可读可写

‘a’:追加内容

‘w+’:打开即清空

前两种的差别在于文件指针初始位置:

  • ‘r+’初始在文件头,read操作将其挪到文件尾,导致第二次read就读不出东西。这种时候就可以通过seek()方法更改文件指针位置,例如seek(0)就是挪到文件开头。
  • ‘a’初始在文件尾,因此我们需要if path.exists(file_path): remove(file_path)来进行伪覆写。

‘w+’不是很讲理,将打开的文件视作全新文件,即使没有任何操作也会清空文件内容。

python各种对象和字符串对象的转化

其实字符串也是对象,但字符串比较偏朴素,和花里胡哨的dictlistset什么的完全比不了。

其他对象可以使用str()转化为字符串,字符串也可以通过list()(列表)、eval(字典)等方法转化为其它类型的对象。

其他类型的强制类型转化也是类似,例如字符串可以转化为整型数,’1’可以转化为 1。

对 C 语言起手的人来说堪称魔法。

获取目前时间

使用time库的ctime()方法。

连缀

'\n'.join([title]),意思是通过换行符号将join里字符串序列连接起来。

收回前言,python字符串也挺花里胡哨的。

python中的for

看上去和 C 里的 for(i=0;i<n;i++);很像,但这里的意思是选取系列中的元素,对所有元素进行以下操作。

如果把系列,也就是soup.find_all('tbody')换成range(),那就和 C 类似了。

另外,pythonfor是可以使用else的。

3
1
2
for each in soup.find_all('tbody'): 
title = each.find('a',class_ = 'topic').get_text(strip=True)

果然面向过程到面向对象的思维转化是个艰难的过程。

从右向左执行

url_dict[input('输入站点代号:')]=input('请输入站点url:'),会先让你输入url,再输入站点代号。反正我觉得没差,就没动它了。


爬虫 plus
http://petertan303.github.io/2023/05/18/Python-爬虫-plus/
作者
peter?
发布于
2023年5月18日
许可协议