为什么这么说?
因为我想学Python很久了,听说它能做很多只有你想不到,没有它做不到的事。 然而事实很残酷,我是懒癌晚期患者,一直只专注在iOS开发当中(尽管做的也不咋好)。但是看到身边搞开发的朋友们都在努力去熟悉其他语言,我开始慌了。这时候我意识到我应该学习一门Objective-C & Swift之外的语言了。但前面说到了,我很懒,我不知道程序猿是不是都懒,学习一门新语言我必须给自己找到一个足够充分的理由,才能驱动我去做这件事。直到有天我无意间进入了某网站,发现页面清新脱俗,女生质量可以说很高了,就像下面这样。 为了确保我不被Cop请去喝茶,图片自行脑补吧
然后我就萌生了一个写Python爬虫,抓取该网站所有作品.torrent
的想法。 这个想法达到了驱动我学Python这件事的要求。紧接着我就开始埋头苦干了。第一次写Python,我有点儿紧张,说的不对的地方请各位大神点击评论,留下您的文字,给我一个改过自新的机会。
第一步 – 安装Python
这个我就不说了,请移步廖雪峰的官方网站-Python教程
,廖老师已经讲的很明了了。
第二步 – 去买一本书
由于我之前没用过Python,所以我先是在京东买了一本《用Python写网络爬虫》
,让快递小哥先帮我运着。
第三步 – 看几个视频教程
相比文字教程,我更喜欢看视频教程,你想的没错,因为快,老师上课给你讲的都是例题,这样你下课才能通过例题去做习题,而不是上来就直接自己看例题,然后做习题。可能我笨吧。但这是我的学习方法。
我去慕课网逛了一圈,以x2的速度看完了两套免费的Python爬虫课程。 如果你之前像我一样一点儿没接触过Python,那么推荐你先看一下Python遇见数据采集
。然后再看这个Python开发简单爬虫
。不然你可能不太理解第二套课程中的设计模式。这是我踩的坑。
这两个课程都不难,而且时间也很短,用x2的速度看足以让你看懂爬虫爬取网页的一些套路。
第四步
根据两套视频课程的学习,相信你对爬取网页的一些套路已经有所了解,然后我们就可以通过两套视频学到的知识,来进行coding
Coding Your First Python Project
我的开发环境是Python3
➜ ~ python3
Python 3.6.0 (default, Feb 11 2017, 01:31:31)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
两个教程本来讲的是urllib
+ BeautifulSoup
的方式进行爬取,但是我一开始就遇到了问题。 就是要爬取的网站要用科学上网的方式才能访问,可是我用urllib
中的request
,无论我怎么设置proxy
,都没有用。Google了很多,得到的答案大部分是用requests
这个库来进行请求。(如果哪位大神有解决方案,我恳请您告诉我,先谢谢了)
于是我就先用了requests
来进行编写
from bs4 import BeautifulSoup # 引入 BeautifulSoup
import request # 引入 requests
import re # 引入 re
然后我们定义一个url
,还有一个header
,user-agent
可以让你简单的伪装成浏览器
url = 'https://xxx.com/actress' #这个地址是AV Star的列表
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36',
"Upgrade-Insecure-Requests": "1"
}
由于我用ss科学上网,所以这里使用的是socks代理,地址你可以查看你的网络偏好设置中的代理Tab
proxies = {
'http': 'socks5h://127.0.0.1:1080',
'https': 'socks5h://127.0.0.1:1080'
}
紧接着我们就可以发起一个请求了
r = requests.get(url, proxies=proxies) # 创建一个 requests 请求对象
soup = BeautifulSoup(r.content, 'html.parser', from_encoding='utf-8') # 创建一个 BeautifulSoup对象
这个时候我们就可以去分析网页的结构了
箭头从上到下依次是
- 该Star主页在网站中的地址
- 图片链接
- Star的名字
我们还知道,列表中每个item的class="card"
,我们就可以用soup
对象对我们要的数据进行取出了
cardList = soup.find_all('div', class_="card") # 取出所有class="card"的内容
然后我们对cardList
进行遍历
starId = 0 # 初始化一个star id,方便我们对接下来数据库的写入
for card in cardList:
sibling_soup = card
starId = starId + 1 # starId自增
# < p class ="card-header-title is-centered" > Star的名字在这个p标签里,我们用.find进行查找
starName = sibling_soup.find('p', class_="card-header-title is-centered").get_text().strip()
# .get_text()是获取这个p标签里的text(不包含其他标签),然后用.strip()对字符串进行去除前后空格的操作
# 然后我们用re.compile去匹配sibling_soup对象中符合 /actress/ 的标签
# 这里我偷了懒,因为网页中每个card里面只有一个a标签内容中含有 /actress/ ,所以我这样写了
starPage = sibling_soup.find('a', href=re.compile(r"/actress/"))['href']
# ['href']是拿到这个a标签中的链接
# 拼接一下网站的域名
starPage = "https://xxx.com" + starPage
# < img class ="card-image" src="https://xxx.com/mono/movie/adult/mide558/mide558pl.jpg" >
# 同样的方式去拿到图片的地址
starImgUrl = sibling_soup.find('img', class_="card-image")['src']
拿到了我们要的数据之后,就可以插入到数据库中了(关于数据库的安装与相关操作,可以观看上面推荐视频1)
# 打开本地数据库
staronnection = pymysql.connect(host='localhost',
user='root',
db='Python',
charset='utf8mb4')
try:
with staronnection.cursor() as cursor:
sql = "insert into `AvStar`(`id`,`name`,`url`,`thumb`) values(%s, %s, %s, %s)"
cursor.execute(sql, (starId, starName, starPage, starImgUrl))
staronnection.commit()
# 插入我们前面拿到的数据
# 关闭数据库
finally:
staronnection.close()
到现在,我们算是完成了60%了,接下来就是进入其中某个Star页面中一探究竟了。看一下页面结构,分析下我们需要的数据
图片中的红框自上而下是
- 该作品的海报
- 该作品的番号
- 该作品.torrent文件的下载地址
ojbk,我们就要这些就行了
我们先只查找每个Star作品列表的前三页,
# 查找该Star的作品列表
for num in [1, 2, 3]:
newUrl = "%s?page=%d" % (starPage, num) # 拼接一下请求地址
newResp = requests.get(newUrl, proxies=proxies) # 发起一个新请求
newSoup = BeautifulSoup(newResp.content, 'html.parser', from_encoding='utf-8') # 创建一个新的BeautifulSoup对象
# <div class="columns">
avList = newSoup.find_all('div', class_="columns") # 拿到列表中每个作品对应的标签内容
# 存种子下载链接
for av in avList:
avSoup = av
# 拿到图片链接
avThumb = avSoup.find('img', class_="image")["src"]
# <h5 class="title is-4 is-spaced"/> 拿到番号
avCode = avSoup.find('a', href=re.compile(r"/torrent/")).get_text().strip()
# 拿到下载链接
avAddress = avSoup.find('a', class_="button is-primary is-fullwidth")["href"]
# 拼接下载链接
avAddress = "https://xxx.com" + avAddress
# 打开数据库,注意到这时我们在数据库中已经有一张AvStar的表用来存储Star的基础信息
# 这里我们要新建一个表,用来存储每部作品的信息
connection = pymysql.connect(host='localhost',
user='root',
db='Python',
charset='utf8mb4')
try:
with connection.cursor() as cursor:
sql = "insert into `AvAddress`(`star_id`,`thumb`, `address`) values(%s, %s, %s)"
cursor.execute(sql, (starId, avThumb, avAddress))
connection.commit()
finally:
connection.close()
# 关闭数据库
# 这里我们发起一个请求 传入.torrent的下载地址
fileResp = requests.get(avAddress, proxies=proxies)
# 点击页面中的下载按钮,通过'检查'进行分析,见下图
# 我们拿到Response Headers中的'Content-Disposition'
# 自定义一个名字
# 最后将文件写入到工程文件夹中
if fileResp.headers.get('Content-Disposition'):
# filename = "xxx.com_mide540_2.torrent
filename = "xxx.com_" + avCode + ".torrent"
open(filename, 'wb').write(fileResp.content)
print("is downloaded" + filename + "onej" + "av" + ".com")
Run 一下吧
至此,代码部分已经完成,我们run一下程序吧(想想还有点儿小激动)
➜ PythonProject git:(master) ✗ python3 xxx
紧接着,我的工程目录下就添加了这么多文件,之后你再用迅雷打开.torrent
,进行下载就行了。
总结
- 先分析你要抓取的网页地址、页面结构,查看其规律性,找到其中的套路
- 用最简单的方式拿到你想要的东西(这大概是Python这门语言的精髓所在了吧)
要解决的问题
- 插入数据库前应该判断一下数据库中有没有当前要插入的数据,如果有,就不插入。
- 我觉得应该加入一个
sleep
什么的,这样每抓一个页面就停一下,可以有效避免被封ip,当然了,小站可能没做这么多,但是大站貌似都会有反爬虫机制吧。 - 总感觉for的效率不是很高,我这里
for
了3
次,时间复杂度为n³
,感觉应该开线程去跑,比如每个Star开一个线程去跑,这样会不会更好一些,但我还没学习到那里。接下来可能就哪里不会点哪里了。 - 最好是下载完
.torrent
之后自动打开下载器进行下载,这样白天上班时,家里的电脑跑着,晚上到家一看,电脑的硬盘爆了。哈哈哈哈
PS: 聪明的大神总能在代码中找到他们想要的,比如说:网址
`你离的越近看,你看到的东西越少`
--- 惊天魔盗团
今天的文章学技术,从兴趣开始分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22902.html