python爬虫图解
发送http请求
以csdn为例,鼠标右键点击检查(或F12
进入开发者模式),然后点击Network,刷新网页,继续点击Name列表中的第一个。我们发现此网站的请求方式为GET,请求头Headers反映用户电脑系统、浏览器版本等信息。
在展开框中选择请求标头,一般拿到Cookie和User-Agent就可以(前者用来加载登陆状态,后者用来伪装浏览器访问)。
构造一个请求
1
2
3
4
5
6
url = 'https://blog.csdn.net/xxx/.html'
header = {
"User-Agent": "Mozilla/5.0 (xxx)",
"Cookie": "uuid_tt_dd=xxxxx"
}
response = requests.get(url, headers=header, verify=False, timeout=10)
verify
设为False可以规避认证问题,同样也存在风险(有可能被第三方攻击)。真正的勇士从不在意这些。
作为进阶,你还可以随机设一些user-agent列表来模拟不同浏览器访问。
解析网页内容
有很多方式,这里使用 BeautifulSoup
(TODO: 不同解析库的异同、哪个是如今最流行的)
1
2
3
4
soup = BeautifulSoup(response.content, 'html.parser')
print(soup.prettify()) # 输出页面内容,帮助你理解页面结构
# 提取文章链接
article_list = soup.find('ul', class_='column_article_list')
基本上,soup.find能解决百分之90的问题,核心在于你要先找到自己想爬取的内容在哪里。 一种方式是,在你想要爬取的内容上右击,选择检查
,会自动引到对应的源代码。
图片区域
以上是通过右击找到了csdn首页的推荐文章列表,如果想要爬取首页这一列所有的推荐文章链接,可以看到,它们都属于<div class="Community">
这个大类。那么你可以:
1
article_list = soup.find('div', class_='Community') # 获取文章列表(小类列表)
实际内容往往层层嵌套,拿到所有小类并不是终极:
图片区域
上图红框里的a
中的href
字段才是你想要的链接。那么你需要找到所有小类列表中的<div class="content">
,再找到a
,再去获取a
中的href
:
1
2
3
4
5
6
7
8
9
10
11
if not article_list:
print("No article list found.")
else:
article_links = []
article_items = article_list.find_all('div', class_='content')
for item in article_items:
a_tag = item.find('a')
if a_tag and 'href' in a_tag.attrs:
link = a_tag['href']
article_links.append(link)
这样就拿到了。后面可以再读取文章内容、标题,然后保存为md什么的,原理是一样的:
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
from markdownify import markdownify as md
# 遍历文章链接,获取文章内容并转换为Markdown格式
for link in article_links:
article_response = requests.get(link, headers=header, verify=False, timeout=10)
article_soup = BeautifulSoup(article_response.content, 'html.parser')
# 提取文章内容
article_content = article_soup.find('div', id='content_views')
if article_content:
# 转换为Markdown格式
markdown_content = md(str(article_content))
# 获取文章标题
title = article_soup.find('h1', class_='title-article').text.strip().replace(" ", "").replace("/", "-")
# 保存为Markdown文件
filename = f"{output_dir}/{title}.md"
with open(filename, 'w', encoding='utf-8') as f:
f.write(markdown_content)
print(f"Saved {filename}")
else:
print(f"No content found for {link}")
wait_time = random.uniform(1, 10) # 模拟人类操作
time.sleep(wait_time)
print("All articles have been processed.")
一些需要注意的小tips:
random.uniform
: 随机生成一个在[x,y]范围内的实数
This post is licensed under CC BY 4.0 by the author.