python爬虫(一)

看到什么写什么

1、for index,value in enumerate(host_tr):

enumerate函数用于将一个可遍历的数据对象组合为一个索引序列,同时列出数据和数据下标,一般都用在for循环中

在这个例子中,enumerate(host_tr)之后的结果是((0,host_tr[0]),(1,host_tr[1]),(2,host_tr[2]),,,,,,,,),所以有index和value的循环

2、if __name__ == '__main__':

每次开启一个程序,都必须写一个主函数作为程序的入口,也就是我们常说的main函数

与Java、C、C++等几种语言不同的是,Python是一种解释型脚本语言,在执行之前不同要将所有代码先编译成中间代码,Python程序运行时是从模块顶行开始,逐行进行翻译执行,所以,最顶层(没有被缩进)的代码都会被执行,所以Python中并不需要一个统一的main()作为程序的入口。在某种意义上讲,“if name==’main:”也像是一个标志,象征着Java等语言中的程序主入口,告诉其他程序员,代码入口在此——这是if __name__==__main__:这条代码的意义之一。

__name__属性是python的一个内置属性,记录了一个字符串

  • 若是在当前文件,则__name__='__main__'

  • 若是导入的文件,__name__是模块名

一般来说开发人员会在模块的最后带有测试代码,为了不在导入模块之后测试代码被执行,就可以在测试代码前加上一条if __name__ == '__main__'

详细解释

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
from lxml import html
import json
import requests
import sys

def GetInformationFromIpshu(ip: str) ->str:
try:
return requests.get(
'https://zh-hans.ipshu.com/ipv4/{}'.format(ip),
headers={
# 根据要爬的网站去按f12看具体的请求头
'accept-encoding': 'gzip,deflate'
# 'cookie':'*******'
# 'accept-language':'******'
# 'sec-ch-ua'
# 'sec-ch-ua-mobile'
# 'sec-ch-ua-platform'
# 'sec-fetch-dest'
# 'sec-fetch-mode'
# 'sec-fetch-site'
# 'sec-fetch-user'
# 'upgrade-insecure-requests'
# 'user-agent'
}
)
except Exception as e:
sys.exit(
print(e)
)

def get_info(ip: str) -> None:
r = GetInformationFromIpshu(ip)
maps = {}
if r.status_code == 200:
tree = html.fromstring(r.content)
host_tr = tree.xpath('//table//td')
k = ''
v = ''
if host_tr:
for index,value in enumerate(host_tr):
if value.tag == 'td':
print(value)
if value.xpath('/a'):
k = str(value.xpath('/a/text()')[0])
print(k)
elif k != '' and v != '':
maps[k] = v
v = ''
k = str(value.xpath('text()')[0])
print(k)
else:v += value.text.strip()
if value.tail.strip() != '':
v += ' ' + value.tail.strip() + ' '
print(v)
if index == len(host_tr) - 1:
maps[k] = v
pass
pass
pass





if __name__ == '__main__':
get_info('13.227.62.117')

4、json文件

JavaScript 对象表示法(JSON)是用于将结构化数据表示为 JavaScript 对象的标准格式,通常用于在网站上表示和传输数据(例如从服务器向客户端发送一些数据,因此可以将其显示在网页上)


Q1:在爬虫写请求头的时候,是在哪个网页按f12,如果是在请求页,在请求有变的时候会有影响吗?e.g.在上面的代码中请求头是在https://zh-hans.ipshu.com/ipv4/13.227.62.117界面按f12查看还是上一个搜索界面按f12查看还是都可以

Q2:在代码中我用xpath拿到了所有table属性的名为td的后代,但在输出的时候发现,由于原网页在某些字段上加了超链接,在输出时value的text值是一个空格,导致无法输出,而真正要输出的值在td下的<a>标签中,目前的思路是在value遍历host_tr的时候加上一个判断判断下面是否还有<a>标签,但是语法方面不太能够实现

2023-5-7 A2:检查输出,添加一个判断,如果输出的text值是一个空格,则取当前td元素下的a元素再提取文本,代码如下

1
2
3
4
5
k = str(value.xpath('text()')[0])
if k == ' ':
a_element = value.xpath('./a')
k = str(a_element[0].xpath('text()')[0])
print(k)

Q3:后续还有text值为空导致整个程序结束的bug,报错原因是IndexError:list index out of range

2023-7-5 A3:在网上查询后暂时的解决方案为使用try——except语句跳过空值,具体如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if host_tr:
for index,value in enumerate(host_tr):
try:
if value.tag == 'td':
if k != '' and v != '':
maps[k] = v
v = ''
k = str(value.xpath('text()')[0])
print(k)
else:v += value.text.strip()
if value.tail.strip() != '':
v += ' ' + value.tail.strip() + ' '
print(v)
if index == len(host_tr) - 1:
maps[k] = v
pass
pass
except IndexError:
continue
pass

赏孩子一口饭吃吧